Statement.hh 72.6 KB
Newer Older
Elemer Lelik's avatar
Elemer Lelik committed
1
/******************************************************************************
Adam Knapp's avatar
Adam Knapp committed
2
 * Copyright (c) 2000-2021 Ericsson Telecom AB
Elemer Lelik's avatar
Elemer Lelik committed
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v2.0
Elemer Lelik's avatar
Elemer Lelik committed
5
 * which accompanies this distribution, and is available at
6
 * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.html
Elemer Lelik's avatar
Elemer Lelik committed
7
8
9
10
11
12
13
14
15
16
 *
 * Contributors:
 *   Balasko, Jeno
 *   Baranyi, Botond
 *   Delic, Adam
 *   Feher, Csaba
 *   Forstner, Matyas
 *   Kovacs, Ferenc
 *   Raduly, Csaba
 *   Szabados, Kristof
17
 *   Szabo, Bence Janos
Elemer Lelik's avatar
Elemer Lelik committed
18
19
20
21
 *   Szabo, Janos Zoltan – initial implementation
 *   Zalanyi, Balazs Andor
 *
 ******************************************************************************/
Elemer Lelik's avatar
Elemer Lelik committed
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
#ifndef _Ttcn_Statement_HH
#define _Ttcn_Statement_HH

#include "AST_ttcn3.hh"

namespace Ttcn {

  /**
   * \addtogroup AST
   *
   * @{
   */

  using namespace Common;

  class StatementBlock;
  class Statement;
  class Assignment;
  class Assignments;
  class ParamAssignment;
  class ParamAssignments;
  class VariableEntry;
  class VariableEntries;
  class ParamRedirect;
46
  class ValueRedirect;
Elemer Lelik's avatar
Elemer Lelik committed
47
48
49
50
51
52
  class LogArgument;
  class LogArguments;
  class IfClause;
  class IfClauses;
  class SelectCase;
  class SelectCases;
53
54
  class SelectUnion;
  class SelectUnions;
55
56
  class SelectClassCase;
  class SelectClassCases;
Elemer Lelik's avatar
Elemer Lelik committed
57
58
59
60
61
62
  class AltGuard;
  class AltGuards;
  class WithAttribPath;
  /* not defined here: */
  class ILT;
  class ILT_branch;
63
64
  class WithAttribPath;
  class ErroneousAttributes;
Elemer Lelik's avatar
Elemer Lelik committed
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82

  /**
   * Represents a %StatementBlock.
   */
  class StatementBlock : public Scope, public Location {
  public:
    enum returnstatus_t {
      RS_NO, /**< indicates that the block does not have return statement
                  at all */
      RS_MAYBE, /**< indicates that some branches of the embedded statements
                     have a return statement but others do not */
      RS_YES /**< indicates that the block or all branches of the
                  embedded statements have a return statement */
    };

    enum exception_handling_t {
      EH_NONE, /**< this is a normal statement block */
      EH_TRY,  /**< this is a try{} block */
83
84
85
      EH_CATCH, /**< this is a catch(exc_str){} block */
      EH_OOP_CATCH, /**< this is a catch block from the object oriented extension */
      EH_OOP_FINALLY /**< this is a finally block from the object oriented extension */
Elemer Lelik's avatar
Elemer Lelik committed
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
    };

  private:
    vector<Statement> stmts;
    /** to store pointers to definitions defined in scope */
    map<Identifier, Definition> defs;
    /** to store goto labels and pointer to their statement */
    map<Identifier, Statement> labels;
    bool checked, labels_checked;
    /** parent sb, if any */
    StatementBlock *my_sb;
    /** my index in the parent sb, if applicable */
    size_t my_sb_index;
    /** The function/altstep/testcase/etc. the StatementBlock belongs to. */
    Definition *my_def;
    /** */
    exception_handling_t exception_handling;
103
    /** List of catch blocks at the end of this statement block (OOP feature) */
104
    vector<StatementBlock> catch_blocks;
105
    /** Optional finally block at the end of this statement block (OOP feature) */
106
    StatementBlock* finally_block;
107
108
109
    /** List of local definitions referenced inside this block
      * (only for the finally block of a normal statement block) */
    map<Common::Assignment*, void> refd_local_defs; // elements not owned
Elemer Lelik's avatar
Elemer Lelik committed
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128

    StatementBlock(const StatementBlock& p);
    StatementBlock& operator=(const StatementBlock& p);
  public:
    StatementBlock();
    virtual ~StatementBlock();
    virtual StatementBlock* clone() const;
    void add_stmt(Statement *p_stmt, bool to_front=false);
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    size_t get_nof_stmts() const { return stmts.size(); }
    Statement *get_stmt_byIndex(size_t p_i) const { return stmts[p_i]; }
    /** Returns the first statement of the block or NULL if there is no such
     * statement. It ignores labels and goes recursively into nested blocks */
    Statement *get_first_stmt() const;
    /* Scope-related functions */
    void register_def(Definition *p_def);
    virtual bool has_ass_withId(const Identifier& p_id);
    virtual Common::Assignment* get_ass_bySRef(Ref_simple *p_ref);
Elemer Lelik's avatar
Elemer Lelik committed
129
    virtual Type *get_mtc_system_comptype(bool is_system);
Elemer Lelik's avatar
Elemer Lelik committed
130
131
132
133
134
135
136
137
    Definition* get_my_def() const { return my_def; }
    virtual Ttcn::StatementBlock *get_statementblock_scope();
    void set_my_sb(StatementBlock *p_sb, size_t p_index);
    StatementBlock* get_my_sb() const { return my_sb; }
    size_t get_my_sb_index() const;
    void set_my_def(Definition *p_def);
    void set_my_ags(AltGuards *p_ags);
    void set_my_laic_stmt(AltGuards *p_ags, Statement *p_loop_stmt);
138
139
    void add_catch_block(StatementBlock* p_catch);
    void set_finally_block(StatementBlock* p_finally);
140
    void add_refd_local_def(Common::Assignment* p_def);
141
    boolean is_in_finally_block() const;
142
    StatementBlock* get_finally_block();
143
    boolean is_empty() const;
Elemer Lelik's avatar
Elemer Lelik committed
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
    returnstatus_t has_return() const;
    /** Used when generating code for interleaved statement. If has
     *  not recv stmt, then the general code generation can be used
     *  (which may use blocks). */
    bool has_receiving_stmt(size_t start_i=0) const;
    /** Used when generating code for interleaved statement. If has
     *  not S_DEF stmt, then there is no need for {}. */
    bool has_def_stmt_i(size_t start_i=0) const;

    void set_exception_handling(exception_handling_t eh) { exception_handling = eh; }
    exception_handling_t get_exception_handling() const { return exception_handling; }

    virtual void dump(unsigned int level) const;
  private:
    /** Returns the index of the last receiving statement after
     *  start_i, or the number of statements if has not recv stmt. */
    size_t last_receiving_stmt_i() const;
    StatementBlock *get_parent_block() const;
    void chk_trycatch_blocks(Statement* prev, Statement* act);
  public:
    /* checking functions */
    void chk();
    /** checks whether all embedded statements are allowed in an interleaved
     * construct */
    void chk_allowed_interleave();
  private:
    void chk_labels();
    void chk_unused_labels();
  public:
    bool has_label(const Identifier& p_id) const;
    Statement *get_label(const Identifier& p_id) const;
    /** Sets the code section selector of all embedded values and
     *  templates to \a p_code_section. */
    void set_code_section(GovernedSimple::code_section_t p_code_section);
178
179
180
181
    /** Generates code for this statement block.
      * '@update' statements may need to generate code into the global variables
      * sections of the module's header and source file, so pointer references to
      * these strings are passed to every statement block that may contain an
182
183
184
      * '@update' statement. 
      * Also generates code for the alt-guards if this is the statement block of an altstep. */
    char* generate_code(char *str, char*& def_glob_vars, char*& src_glob_vars, AltGuards* alt_guards = NULL);
185
    char* generate_code_finally(char* str, char*& def_glob_vars, char*& src_glob_vars);
Elemer Lelik's avatar
Elemer Lelik committed
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
    void ilt_generate_code(ILT *ilt);

    virtual void set_parent_path(WithAttribPath* p_path);
  };

  /**
   * Represents a statement (FunctionStatement) in dynamic part of
   * TTCN-3.
   */
  class Statement : public Node, public Location {
  public:
    enum statementtype_t {
      /* erroneous statement */
      S_ERROR,
      /* ambiguous statements */
      S_START_UNDEF, // undefstartstop
      S_STOP_UNDEF, // undefstartstop
      S_UNKNOWN_INSTANCE, // ref_pard
      S_UNKNOWN_INVOKED, // fau_refd
      /* basic statements */
      S_DEF, // def (const or template def; variable or timer instance)
      S_ASSIGNMENT, // ass
      S_FUNCTION_INSTANCE, // ref_pard
      S_FUNCTION_INVOKED, // fau_refd
      S_BLOCK, // block
      S_LOG, // logargs
      S_LABEL, // label
      S_GOTO, // go_to
      S_BREAK, // brk_cnt
      S_CONTINUE, // brk_cnt
      S_IF, // if_stmt
      S_SELECT, // select
218
      S_SELECTUNION, // select union
219
      S_SELECT_CLASS, // select class
Elemer Lelik's avatar
Elemer Lelik committed
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
      S_FOR, // loop
      S_WHILE, // loop
      S_DOWHILE, // loop
      S_STOP_EXEC, // -
      S_STOP_TESTCASE, // logargs
      /* behaviour statements */
      S_ALT, // ags
      S_REPEAT, // ags BUT only a pointer (my_ags)
      S_INTERLEAVE, // ags
      S_ALTSTEP_INSTANCE, // ref_pard
      S_ALTSTEP_INVOKED, // fau_refd
      S_RETURN, // returnexpr
      /* default statements */
      S_ACTIVATE, // ref_pard
      S_ACTIVATE_REFD, //activate_refd
      S_DEACTIVATE, // deactivate
      /* communication (port) statements */
      S_SEND, // port send_par to_clause
      S_CALL, // port send_par call to_clause
      S_REPLY, // port send_par reply_val to_clause
      S_RAISE, // port raise_signature send_par to_clause
      S_RECEIVE, // port rcv_par from_clause redirect.value
		 // redirect.sender
      S_TRIGGER, // port rcv_par from_clause redirect.value
		 // redirect.sender
      S_GETCALL, // port rcv_par from_clause redirect.value
		 // redirect.sender redirect.par_spec
      S_GETREPLY, // port rcv_par getreply_valuematch from_clause
		  // redirect.value redirect.sender redirect.par_spec
      S_CATCH, // port ctch.signature rcv_par ctch.timeout from_clause
	       // redirect.value redirect.sender
      S_CHECK, // port from_clause redirect.sender
      S_CHECK_RECEIVE,
      S_CHECK_GETCALL,
      S_CHECK_GETREPLY,
      S_CHECK_CATCH,
      S_CLEAR, // port
      S_START_PORT, // port
      S_STOP_PORT, // port
      S_HALT, // port
260
      S_SETSTATE, // setstate_op
Elemer Lelik's avatar
Elemer Lelik committed
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
      /* component statements */
      S_START_COMP, // comp_op
      S_START_COMP_REFD, // comp_op
      S_STOP_COMP, // comp_op
      S_DONE, // comp_op
      S_KILL, // comp_op
      S_KILLED, // comp_op
      /* configuration statements */
      S_CONNECT, // config
      S_MAP, // config
      S_DISCONNECT, // config
      S_UNMAP, // config
      /* timer statements */
      S_START_TIMER, // timer
      S_STOP_TIMER, // timer
      S_TIMEOUT, // timer
      /* verdict statement */
      S_SETVERDICT, // verdictval
      /* SUT statement */
      S_ACTION, // logargs
      /* control statement */
      S_TESTCASE_INSTANCE, // testcase_inst
      S_TESTCASE_INSTANCE_REFD, //execute_refd
Elemer Lelik's avatar
Elemer Lelik committed
284
285
      /* TTCN-3 Profiler statements */
      S_START_PROFILER,
Elemer Lelik's avatar
Elemer Lelik committed
286
287
288
      S_STOP_PROFILER,
      /* Conversion statements */
      S_STRING2TTCN, // convert_op
289
290
      S_INT2ENUM, // convert_op
      /* update statement */
291
      S_UPDATE, // update_op
292
      /* encoding-related statements */
293
294
      S_SETENCODE, // setencode_op
      S_RAISE_OOP // raise_op (this is the raise statement from the object oriented extension)
Elemer Lelik's avatar
Elemer Lelik committed
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
    };

    enum component_t {
      C_ALL,
      C_ANY
    };

  private:
    statementtype_t statementtype;
    /// The statement block this statement belongs to.
    StatementBlock *my_sb;
    union {
      Assignment *ass; ///< used by S_ASSIGNMENT
      Definition *def; ///< used by S_DEF
      StatementBlock *block; ///< used by S_BLOCK
      LogArguments *logargs; ///< used by S_ACTION, S_LOG, S_STOP_TESTCASE
      struct {
        Reference *portref; /**< NULL means any/all */
313
314
        bool translate; /**< true if it an operation from a translation function:
                         * For example: port.send(3) or port.receive(4)*/
315
        bool anyfrom;
Elemer Lelik's avatar
Elemer Lelik committed
316
317
318
319
	union {
	  struct {
	    TemplateInstance *sendpar;
	    Value *toclause;
320
	    Reference* timestampredirect;
Elemer Lelik's avatar
Elemer Lelik committed
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
	    union {
	      struct {
		Value *timer;
		bool nowait;
		AltGuards *body;
	      } call;
	      Value *replyval;
	      struct {
		Reference *signature_ref;
		Type *signature; /**< only for caching */
	      } raise;
	    };
	  } s;
	  struct {
	    TemplateInstance *rcvpar;
	    TemplateInstance *fromclause;
	    struct {
338
	      ValueRedirect *value;
Elemer Lelik's avatar
Elemer Lelik committed
339
340
	      ParamRedirect *param;
	      Reference *sender;
341
	      Reference* index;
342
	      Reference* timestamp;
Elemer Lelik's avatar
Elemer Lelik committed
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
	    } redirect;
	    union {
	      TemplateInstance *getreply_valuematch;
	      struct {
		Reference *signature_ref;
		Type *signature; /**< only for caching */
		bool timeout;
		bool in_call, call_has_timer;
	      } ctch; /**< catch */
	    };
	  } r;
	};
      } port_op; /**< used by S_SEND, S_CALL, S_REPLY, S_RAISE,
      S_RECEIVE, S_CHECK_RECEIVE, S_TRIGGER,
      S_GETCALL, S_CHECK_GETCALL, S_GETREPLY, S_CHECK_GETREPLY,
      S_CATCH, S_CHECK_CATCH, S_CHECK, S_CLEAR,
      S_START_PORT, S_STOP_PORT, S_HALT */

      struct {
        Reference *timerref; /**< 0 means any/all */
        Value *value;
364
365
        bool any_from;
        Reference* index_redirect;
Elemer Lelik's avatar
Elemer Lelik committed
366
367
368
369
370
371
372
      } timer_op; ///< used by S_START_TIMER, S_STOP_TIMER, S_TIMEOUT

      struct {
        Value *compref1;
        Reference *portref1;
        Value *compref2;
        Reference *portref2;
373
        bool translate; // true if a map statement enables translation mode
374
375
376
377
378
        union {
          ParsedActualParameters* parsed_params;
          ActualParList* ap_list;
        };
        FormalParList* fp_list; // not owned
Elemer Lelik's avatar
Elemer Lelik committed
379
380
381
382
383
      } config_op; ///< used by S_CONNECT, S_MAP, S_DISCONNECT, S_UNMAP

      struct {
        Value *compref; /**< if S_STOP_COMP, S_KILL then compref==0
                             means ALL */
384
385
386
        bool any_from;
        Reference* index_redirect;

Elemer Lelik's avatar
Elemer Lelik committed
387
388
389
390
391
        union {
          component_t any_or_all;
          /**< used if S_DONE, S_KILLED and compref==0 */
          struct {
            TemplateInstance *donematch;
392
            ValueRedirect *redirect;
Elemer Lelik's avatar
Elemer Lelik committed
393
          } donereturn; /**< used if S_DONE and compref!=0 */
394
          Reference *funcinstref; /**< used if S_START_COMP */
Elemer Lelik's avatar
Elemer Lelik committed
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
          struct {/** used if S_START_COMP_REFD */
            Value *value;
            union {
              ParsedActualParameters *t_list1;
              ActualParList *ap_list2;
            };
          } derefered;
        };
      } comp_op; /**< used by S_START_COMP, S_START_COMP_REFD, S_STOP_COMP,
      S_KILL, S_KILLED, S_DONE */

      struct {
        Value *verdictval;
        LogArguments *logargs;
      } setverdict;

      Value *deactivate; ///< used by S_DEACTIVATE
      AltGuards *ags;    ///< used by S_ALT and S_INTERLEAVE

      struct {
415
        Reference *tcref;
Elemer Lelik's avatar
Elemer Lelik committed
416
417
418
419
420
421
422
423
424
425
426
427
        Value *timerval;
      } testcase_inst;

      struct {
        Value *value;
        union {
          TemplateInstances *t_list1;
          ActualParList *ap_list2;
        };
        Value *timerval;
      } execute_refd;

428
      Reference *ref_pard;
Elemer Lelik's avatar
Elemer Lelik committed
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471

      struct {
        Value *value;
        union {
          ParsedActualParameters *t_list1;
          ActualParList *ap_list2;
        };
      } fau_refd; /**< used by S_ACTIVATE_REFD, S_UNKNOWN_INVOKED,
      S_FUNCTION_INVOKED, S_ALTSTEP_INVOKED (function, altstep, or unknown) */

      struct {
        union {
          Value *expr;
          struct {
            bool varinst;
            union {
              Assignment *init_ass;
              Definitions *init_varinst;
            };
            Value *finalexpr;
            Assignment *step;
          } for_stmt;
        };
        StatementBlock *block;
        string *label_next; /**< label for continue, left as 0 if not needed */
        string *il_label_end; /**< label for break in interleave - if needed */
        bool has_cnt; /**< Has continue with effect on the loop */
        bool has_brk; /**< Has break with effect on the loop */
        bool has_cnt_in_ags; /**< Has continue inside embedded ags(AltGuards)*/
        bool iterate_once; /**< do-while loop has constant false expr */
        bool is_ilt; /**< Is compiled specially with ilt_generate_code_... */
      } loop;

      struct {
        IfClauses *ics; /**< if-clauses */
        StatementBlock *elseblock; /**< the last else-block */
	Location *elseblock_location; /**< location of the last else-block */
      } if_stmt;

      struct {
        Value *expr;
        SelectCases *scs;
      } select;
472
473
474
475
476
      
      struct {
        Value *expr;
        SelectUnions *sus;
      } select_union;
477
478
479
480
481
      
      struct {
        Reference* ref;
        SelectClassCases* sccs;
      } select_class;
Elemer Lelik's avatar
Elemer Lelik committed
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508

      struct {
        Value *v;
        Template *t;
        bool gen_restriction_check; // set in chk_return()
      } returnexpr;

      struct {
        Identifier *id;
        size_t stmt_idx; /**< index of the statement within its block */
        string *clabel; /**< C++ label identifier in the generated code */
	bool used;
      } label;

      struct {
        Identifier *id;
        size_t stmt_idx; /**< index of the statement within its block */
        Statement *label; /**< points to the referenced label */
	bool jumps_forward; /**< indicates the direction of the jump */
      } go_to;

      struct {
        Statement *loop_stmt; /**< loop that can be exited by the break*/
        AltGuards *ags; /**< altstep, alt, interleave, call */
      } brk_cnt; // break or continue

      struct {
509
        Reference *ref;
Elemer Lelik's avatar
Elemer Lelik committed
510
511
512
513
514
515
        Value *val;
      } undefstartstop;

      struct { // S_STRING2TTCN
        Value* val;
        Reference* ref;
Elemer Lelik's avatar
Elemer Lelik committed
516
      } convert_op;
517
518
519
520
521
522
      
      struct {
        Reference* ref;
        WithAttribPath* w_attrib_path;
        ErroneousAttributes* err_attrib;
      } update_op; /**< S_UPDATE */
523
524
525
526
527
      
      struct {
        Value* val;
        TemplateInstance* ti;
      } setstate_op; /**< S_SETSTATE */
528
529
530
531
532
      
      struct {
        Type* type;
        Value* encoding;
      } setencode_op;
533
534
535
536
537
538
539
540
541
      
      struct {
        bool checked;
        union {
          TemplateInstance* ti;
          Value* v;
        };
      } raise_op;
       /**< S_RAISE_OOP */
Elemer Lelik's avatar
Elemer Lelik committed
542
543
544
545
546
547
    };

    Statement(const Statement& p); ///< copy disabled
    Statement& operator=(const Statement& p); ///< assignment disabled
    void clean_up();
  public:
Elemer Lelik's avatar
Elemer Lelik committed
548
549
    /** Constructor used by S_ERROR, S_STOP_EXEC and S_REPEAT, S_BREAK,
     *  S_CONTINUE, S_START_PROFILER and S_STOP_PROFILER */
Elemer Lelik's avatar
Elemer Lelik committed
550
    Statement(statementtype_t p_st);
551
552
    /** Constructor used by S_START_UNDEF S_STOP_UNDEF and S_TESTCASE_INSTANCE */
    Statement(statementtype_t p_st, Reference *p_ref, Value *p_val);
Elemer Lelik's avatar
Elemer Lelik committed
553
    /** Constructor used by S_FUNCTION_INSTANCE, S_ALTSTEP_INSTANCE,
554
555
556
     *  S_UNKNOWN_INSTANCE, S_ACTIVATE, S_CLEAR, S_START_PORT and S_STOP_PORT.
     *  p_ref==0 means all port. S_STOP_TIMER (p_ref==0: all timer) */
    Statement(statementtype_t p_st, Reference *p_ref);
Elemer Lelik's avatar
Elemer Lelik committed
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
    /** S_ACTIVATE_REFD , S_FUNCTION_INSTANCE_REFD */
    Statement(statementtype_t p_st, Value *p_derefered_value,
              ParsedActualParameters *p_ap_list);
    /** Constructor used by S_DEF */
    Statement(statementtype_t p_st, Definition *p_def);
    /** Constructor used by S_ASSIGNMENT */
    Statement(statementtype_t p_st, Assignment *p_ass);
    /** Constructor used by S_BLOCK */
    Statement(statementtype_t p_st, StatementBlock *p_block);
    /** Constructor used by S_LOG and S_ACTION */
    Statement(statementtype_t p_st, LogArguments *p_logargs);
    /** Constructor used by S_LABEL and S_GOTO */
    Statement(statementtype_t p_st, Identifier *p_id);
    /** Constructor used by S_IF */
    Statement(statementtype_t p_st, IfClauses *p_ics, StatementBlock *p_block,
              Location *p_loc);
    /** Constructor used by S_SELECT */
    Statement(statementtype_t p_st, Value *p_expr, SelectCases *p_scs);
575
576
    /** Constructor used by S_SELECTUNION */
    Statement(statementtype_t p_st, Value *p_expr, SelectUnions *p_sus);
577
578
    /** Constructor used by S_SELECT_CLASS */
    Statement(statementtype_t p_st, Reference *p_ref, SelectClassCases *p_sccs);
Elemer Lelik's avatar
Elemer Lelik committed
579
580
581
582
583
584
585
586
587
    /** Constructor used by S_FOR */
    Statement(statementtype_t p_st, Definitions *p_defs, Assignment *p_ass,
              Value *p_final, Assignment *p_step, StatementBlock *p_block);
    /** Constructor used by S_WHILE, S_DOWHILE */
    Statement(statementtype_t p_st, Value *p_val, StatementBlock *p_block);
    /** Constructor used by S_ALT and S_INTERLEAVE */
    Statement(statementtype_t p_st, AltGuards *p_ags);
    /** Constructor used by S_RETURN */
    Statement(statementtype_t p_st, Template *p_temp);
588
    /** Constructor used by S_DEACTIVATE, S_STOP_COMP, S_KILL, S_SETSTATE */
Elemer Lelik's avatar
Elemer Lelik committed
589
    Statement(statementtype_t p_st, Value *p_val);
590
591
592
    /** Constructor used by S_KILLED */
    Statement(statementtype_t p_st, Value *p_val, bool p_any_from,
              Reference* p_index_redirect);
Elemer Lelik's avatar
Elemer Lelik committed
593
594
595
596
    /** Constructor used by S_SETVERDICT */
    Statement(statementtype_t p_st, Value *p_val, LogArguments *p_logargs);
    /** Constructor used by S_SEND */
    Statement(statementtype_t p_st, Reference *p_ref,
597
598
              TemplateInstance *p_templinst, Value *p_val,
              Reference* p_timestampredirect, bool p_translate);
Elemer Lelik's avatar
Elemer Lelik committed
599
600
601
    /** Constructor used by S_CALL */
    Statement(statementtype_t p_st, Reference *p_ref,
              TemplateInstance *p_templinst, Value *p_timerval,
602
603
              bool p_nowait, Value *p_toclause, Reference* p_timestampredirect,
              AltGuards *p_callbody);
Elemer Lelik's avatar
Elemer Lelik committed
604
605
606
    /** Constructor used by S_REPLY */
    Statement(statementtype_t p_st, Reference *p_ref,
              TemplateInstance *p_templinst, Value *p_replyval,
607
              Value *p_toclause, Reference* p_timestampredirect);
Elemer Lelik's avatar
Elemer Lelik committed
608
609
610
    /** Constructor used by S_RAISE */
    Statement(statementtype_t p_st, Reference *p_ref,
              Reference *p_sig, TemplateInstance *p_templinst,
611
              Value *p_toclause, Reference* p_timestampredirect);
Elemer Lelik's avatar
Elemer Lelik committed
612
613
    /** Constructor used by S_RECEIVE, S_CHECK_RECEIVE and
     *  S_TRIGGER. p_ref==0 means any port. */
614
    Statement(statementtype_t p_st, Reference *p_ref, bool p_anyfrom,
Elemer Lelik's avatar
Elemer Lelik committed
615
              TemplateInstance *p_templinst, TemplateInstance *p_fromclause,
616
              ValueRedirect *p_redirectval, Reference *p_redirectsender,
617
618
              Reference* p_redirectindex, Reference* p_timestamp_redirect,
              bool p_translate);
Elemer Lelik's avatar
Elemer Lelik committed
619
620
    /** Constructor used by S_GETCALL and S_CHECK_GETCALL. p_ref==0
     *  means any port. */
621
    Statement(statementtype_t p_st, Reference *p_ref, bool p_anyfrom,
Elemer Lelik's avatar
Elemer Lelik committed
622
              TemplateInstance *p_templinst, TemplateInstance *p_fromclause,
623
              ParamRedirect *p_redirectparam, Reference *p_redirectsender,
624
              Reference* p_redirectindex, Reference* p_timestamp_redirect);
Elemer Lelik's avatar
Elemer Lelik committed
625
626
    /** Constructor used by S_GETREPLY and S_CHECK_GETREPLY. p_ref==0
     *  means any port. */
627
    Statement(statementtype_t p_st, Reference *p_ref, bool p_anyfrom,
Elemer Lelik's avatar
Elemer Lelik committed
628
629
              TemplateInstance *p_templinst, TemplateInstance *p_valuematch,
              TemplateInstance *p_fromclause,
630
              ValueRedirect *p_redirectval, ParamRedirect *p_redirectparam,
631
632
              Reference *p_redirectsender, Reference* p_redirectindex,
              Reference* p_timestamp_redirect);
Elemer Lelik's avatar
Elemer Lelik committed
633
634
    /** Constructor used by S_CATCH and S_CHECK_CATCH. p_ref==0 means
     *  any port. */
635
    Statement(statementtype_t p_st, Reference *p_ref,  bool p_anyfrom,
Elemer Lelik's avatar
Elemer Lelik committed
636
637
              Reference *p_sig, TemplateInstance *p_templinst,
              bool p_timeout, TemplateInstance *p_fromclause,
638
              ValueRedirect *p_redirectval, Reference *p_redirectsender,
639
              Reference* p_redirectindex, Reference* p_timestamp_redirect);
Elemer Lelik's avatar
Elemer Lelik committed
640
    /** Constructor used by S_CHECK. p_ref==0 means any port. */
641
642
    Statement(statementtype_t p_st, Reference *p_ref, bool p_anyfrom,
              TemplateInstance *p_fromclause, Reference *p_redirectsender,
643
              Reference* p_redirectindex, Reference* p_timestamp_redirect);
644
645
646
    /** Constructor used by S_TIMEOUT (p_ref==0: any timer)*/
    Statement(statementtype_t p_st, Reference *p_ref, bool p_any_from,
              Reference* p_redirectindex);
Elemer Lelik's avatar
Elemer Lelik committed
647
648
649
650
651
    /** Constructor used by S_START_COMP_REFD */
    Statement(statementtype_t p_st, Value *p_compref, Value *p_derefered_value,
              ParsedActualParameters *p_ap_list);
    /** Constructor used by S_DONE */
    Statement(statementtype_t p_st, Value *p_compref,
652
653
              TemplateInstance *p_donematch, ValueRedirect *p_redirect,
              Reference* p_index_redirect, bool p_any_from);
Elemer Lelik's avatar
Elemer Lelik committed
654
655
656
657
658
    /** Constructor used by S_DONE, S_KILLED */
    Statement(statementtype_t p_st, component_t p_anyall);
    /** Constructor used by S_CONNECT, S_DISCONNECT, S_MAP, S_UNMAP */
    Statement(statementtype_t p_st,
              Value *p_compref1, Reference *p_portref1,
659
660
              Value *p_compref2, Reference *p_portref2,
              ParsedActualParameters* p_params);
Elemer Lelik's avatar
Elemer Lelik committed
661
662
663
    /** Constructor used by S_ACTIVATE_REFD */
    Statement(statementtype_t p_st, Value *p_derefered_value,
               TemplateInstances *p_ap_list, Value *p_val);
664
    /** Constructor used by S_STRING2TTCN, S_INT2ENUM and S_START_COMP */
Elemer Lelik's avatar
Elemer Lelik committed
665
    Statement(statementtype_t p_st, Value* p_val, Reference* p_ref);
666
667
    /** Constructor used by S_UPDATE */
    Statement(statementtype_t p_st, Reference* p_ref, MultiWithAttrib* p_attrib);
668
669
    /** Constructor used by S_SETSTATE */
    Statement(statementtype_t p_st, Value* p_val, TemplateInstance* p_ti);
670
671
    /** Constructor used by S_SETENCODE */
    Statement(statementtype_t p_st, Type* p_type, Value* p_encoding);
672
673
    /** Constructor used by S_RAISE_OOP */
    Statement(statementtype_t p_st, TemplateInstance* p_ti);
Elemer Lelik's avatar
Elemer Lelik committed
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
    virtual ~Statement();
    virtual Statement* clone() const;
    virtual void dump(unsigned int level) const;
    statementtype_t get_statementtype() const { return statementtype; }
    StatementBlock *get_my_sb() const { return my_sb; }
    size_t get_my_sb_index() const;
    const char *get_stmt_name() const;
    const Identifier& get_labelid() const;
    /** Returns whether the label is used by goto statements, applicable if
     * \a this is a label (S_LABEL) */
    bool label_is_used() const;
    /** Returns whether the goto statement jumps forward in the statement block,
     * applicable if \a this is a goto (S_GOTO) */
    bool goto_jumps_forward() const;
  private:
    /** Returns the c++ identifier of the label, applicable if \a this is a
     * label (S_LABEL) */
    const string& get_clabel();
  public:
    /** Applicable if \a this is a definition (S_DEF) */
    Definition *get_def() const;
    /** Applicable if \a this is an alt (S_ALT) or interleave (S_INTERLEAVE) */
    AltGuards *get_ags() const;
    /** Applicable if \a this is a block (S_BLOCK) or a loop
     * (S_FOR, S_WHILE, S_DOWHILE) */
    StatementBlock *get_block() const;
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    /** pass down to embedded statementblocks */
    void set_my_sb(StatementBlock *p_sb, size_t p_index);
    void set_my_def(Definition *p_def);
    /** used in S_REPEAT */
    void set_my_ags(AltGuards *p_ags);
    /** used in S_BREAK and S_CONTINUE */
    void set_my_laic_stmt(AltGuards *p_ags, Statement *p_loop_stmt);
    /** Returns true if the statement following \a this in a statement
     *  block will never be executed sequentially after \a this. */
    bool is_terminating() const;
    StatementBlock::returnstatus_t has_return() const;
    bool is_receiving_stmt() const;
    bool has_receiving_stmt() const;
    /** Indicates whether the C++ equivalent of the statement can
     *  return ALT_REPEAT. Applicable to receiving statements only. */
    bool can_repeat() const;
    /* checking functions */
    void chk();
    /** checks whether the statement (including all embedded statements) are
     * allowed in an interleaved construct */
    void chk_allowed_interleave();
723
724
725
726
727
728
729
730
731
732
733
734
735
    
    /** Checks the index redirect in a port, timer or component array operation.
      *
      * @param p_index_ref reference to variable or parameter for storing the index
      * @param p_array_dims dimensions of the port, timer or component array
      * @param p_any_from presence of the 'any from' clause before the array
      * @param p_array_type string containing "port", "timer" or "component"
      * (used in error messages)
      *
      * @note This function is also called by expressions containing timer or
      * component operations in the Value class. */
    static void chk_index_redirect(Reference* p_index_ref,
      ArrayDimensions* p_array_dims, bool p_any_from, const char* p_array_type);
Elemer Lelik's avatar
Elemer Lelik committed
736
737
738
739
740
741
742
743
744
745
746
747
748
  private:
    void chk_start_undef();
    void chk_stop_undef();
    void chk_unknown_instance();
    void chk_unknown_invoke();
    void chk_assignment();
    void chk_function();
    void chk_block();
    /* checks log, action */
    void chk_log_action(LogArguments *logargs);
    void chk_goto();
    void chk_if();
    void chk_select();
749
    void chk_select_union();
750
    void chk_select_class();
Elemer Lelik's avatar
Elemer Lelik committed
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
    void chk_for();
    void chk_while();
    void chk_do_while();
    void chk_break();
    void chk_continue();
    void chk_alt();
    void chk_repeat();
    void chk_interleave();
    void chk_altstep();
    void chk_return();
    void chk_activate();
    void chk_activate_refd();
    void chk_deactivate();
    void chk_send();
    void chk_call();
    void chk_reply();
    void chk_raise();
    /* checks receive, check-receive trigger */
    void chk_receive();
    /* checks getcall, check-getcall */
    void chk_getcall();
    /* checks getreply, check-getreply */
    void chk_getreply();
    /* checks catch, check-catch */
    void chk_catch();
    void chk_check();
    void chk_clear();
    /** checks start port, stop port, halt */
    void chk_start_stop_port();
    void chk_start_comp();
    void chk_start_comp_refd();
    /* checks stop comp, kill, killed */
    void chk_stop_kill_comp();
    void chk_done();
    void chk_killed();
    /* checks connect and disconnect */
    void chk_connect();
    /* checks map and unmap */
    void chk_map();
790
    void chk_map_params(PortTypeBody* p_system_port);
Elemer Lelik's avatar
Elemer Lelik committed
791
    void chk_start_timer();
792
793
    void chk_stop_timer();
    void chk_timer_timeout();
Elemer Lelik's avatar
Elemer Lelik committed
794
795
796
797
    void chk_setverdict();
    void chk_execute();
    void chk_execute_refd();

798
    /** Checks whether \a p_ref points to a port, port parameter or port array.
Elemer Lelik's avatar
Elemer Lelik committed
799
     *  If \a p_ref refers to a port array the array indices within \a
800
801
802
803
     *  p_ref are also checked. If \a p_any_from is true, then the reference
     *  must point to a port array, otherwise it must point to a port.
     *  Returns a pointer to the port type if available or NULL otherwise. */
    Type *chk_port_ref(Reference *p_ref, bool p_any_from = false);
Elemer Lelik's avatar
Elemer Lelik committed
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
    /** Checks the `to' clause of a port operation. Field
     *  port_op.s.toclause shall be a component reference (or an
     *  address) depending on the extension attributes of \a
     *  port_type. */
    void chk_to_clause(Type *port_type);
    /** Checks the `from' clause and `sender' redirect of a port
     *  operation.  Type of field port_op.r.fromclause and
     *  port_op.r.redirect.sender shall be a component type (or
     *  address) depending on the extension attributes of \a
     *  port_type. */
    void chk_from_clause(Type *port_type);
    /** Checks the response and exception handling part of a call
     *  operation.  Arguments \a port_type \a signature point to the
     *  port type and signature used in the call operation. */
    void chk_call_body(Type *port_type, Type *signature);
819
    /** Determines and returns the type of the incoming or outgoing message or
Elemer Lelik's avatar
Elemer Lelik committed
820
     *  signature based on a template instance \a p_ti. */
821
    static Type *get_msg_sig_type(TemplateInstance *p_ti);
Elemer Lelik's avatar
Elemer Lelik committed
822
823
824
825
826
827
    /** Checks the variable reference of a sender redirect.  The type
     *  of the variable (or NULL in case of non-existent sender clause
     *  or error) is returned.  The type of the variable is also
     *  checked: it shall be a component type or \a address_type (if
     *  it is not NULL). */
    Type *chk_sender_redirect(Type *address_type);
828
    void chk_timestamp_redirect(Type* port_type, bool outgoing);
Elemer Lelik's avatar
Elemer Lelik committed
829
830
831
832
    /** Checks whether \a p_ref points to a signature. The type
     *  describing the respective signature is returned or NULL in
     *  case of error. */
    static Type *chk_signature_ref(Reference *p_ref);
833
    /** Checks whether \a p_ref points to a timer, timer parameter or timer array.
Elemer Lelik's avatar
Elemer Lelik committed
834
     *  If \a p_ref refers to a timer array the array indices within
835
836
837
838
839
840
841
842
843
844
845
846
     *  \a p_ref are also checked. If \a p_any_from is true, then the reference
     *  must point to a port array, otherwise it must point to a port.*/
    static void chk_timer_ref(Reference *p_ref, bool p_any_from = false);
    /** Checks whether \a p_val is a component or component array reference
     *  (i.e. its type is a component or component array type).
     *  Returns a pointer to the component or component array type if available
     *  or NULL otherwise. Flags \a allow_mtc and \a allow_system indicate whether
     *  the mtc or system component reference is acceptable in this context.
     *  Flag p_any_from indicates whether the 'any from' clause was used on \a p_val
     *  (in which case it must be a component array) or not (in which case it
     *  must be a component). */
    Type *chk_comp_ref(Value *p_val, bool allow_mtc, bool allow_system, bool p_any_from = false);
Elemer Lelik's avatar
Elemer Lelik committed
847
848
849
850
851
852
853
854
    /** Checks an endpoint for a port connection or mapping. Parameter
     *  \a p_compref is a component reference, \a p_portref refers to
     *  a port within the corresponding component type.  A pointer to
     *  the referred port type (or NULL in case of error) is
     *  returned. */
    Type *chk_conn_endpoint(Value *p_compref, Reference *p_portref,
                            bool allow_system);
    void chk_string2ttcn();
Elemer Lelik's avatar
Elemer Lelik committed
855
    void chk_int2enum();
856
    void chk_update();
857
    void chk_setstate();
858
    void chk_setencode();
859
    void chk_raise_oop();
Elemer Lelik's avatar
Elemer Lelik committed
860
861
862
863
  public:
    /** Sets the code section selector of all embedded values and
     *  templates to \a p_code_section. */
    void set_code_section(GovernedSimple::code_section_t p_code_section);
864
    char* generate_code(char *str, char*& def_glob_vars, char*& src_glob_vars);
Elemer Lelik's avatar
Elemer Lelik committed
865
866
    void generate_code_expr(expression_struct *expr);
    void ilt_generate_code(ILT *ilt);
867
868
869
870
871
872
873
874
    
    /** Generates code for an index redirect. (A new class is generated for each
      * redirect, inheriting the Index_Redirect class.)
      *
      * @note This function is also called by expressions containing timer or
      * component operations in the Value class. */
    static void generate_code_index_redirect(expression_struct* expr,
      Reference* p_ref, Scope* p_scope);
Elemer Lelik's avatar
Elemer Lelik committed
875
876
877
878
879
880
881
882
883

    /** Needed by implicit omit. Pushes attrib path down to definitions
     */
    virtual void set_parent_path(WithAttribPath* p_path);
  private:
    char *generate_code_standalone(char *str);
    /** used for function and altstep instances */
    char *generate_code_funcinst(char *str);
    char *generate_code_invoke(char *str);
884
    char *generate_code_block(char *str, char*& def_glob_vars, char*& src_glob_vars);
Elemer Lelik's avatar
Elemer Lelik committed
885
886
887
888
889
    char *generate_code_log(char *str);
    char* generate_code_string2ttcn(char *str);
    char *generate_code_testcase_stop(char *str);
    char *generate_code_label(char *str);
    char *generate_code_goto(char *str);
890
891
892
    char *generate_code_if(char *str, char*& def_glob_vars, char*& src_glob_vars);
    char *generate_code_select(char *str, char*& def_glob_vars, char*& src_glob_vars);
    char *generate_code_select_union(char *str, char*& def_glob_vars, char*& src_glob_vars);
893
    char *generate_code_select_class(char *str, char*& def_glob_vars, char*& src_glob_vars);
894
895
896
    char *generate_code_for(char *str, char*& def_glob_vars, char*& src_glob_vars);
    char *generate_code_while(char *str, char*& def_glob_vars, char*& src_glob_vars);
    char *generate_code_dowhile(char *str, char*& def_glob_vars, char*& src_glob_vars);
Elemer Lelik's avatar
Elemer Lelik committed
897
898
899
    char *generate_code_break(char *str);
    char *generate_code_continue(char *str);
    char *generate_code_repeat(char *str);
900
    char *generate_code_interleave(char *str, char*& def_glob_vars, char*& src_glob_vars);
Elemer Lelik's avatar
Elemer Lelik committed
901
902
903
904
905
906
    void ilt_generate_code_interleave(ILT *ilt);
    void ilt_generate_code_alt(ILT *ilt);
    void ilt_generate_code_receiving(ILT *ilt);
    void ilt_generate_code_def(ILT *ilt);
    void ilt_generate_code_if(ILT *ilt);
    void ilt_generate_code_select(ILT *ilt);
907
    void ilt_generate_code_select_union(ILT *ilt);
908
    void ilt_generate_code_select_class(ILT *ilt);
Elemer Lelik's avatar
Elemer Lelik committed
909
910
911
912
913
914
915
916
917
    void ilt_generate_code_call(ILT *ilt);
    void ilt_generate_code_for(ILT *ilt);
    void ilt_generate_code_while(ILT *ilt);
    void ilt_generate_code_dowhile(ILT *ilt);
    char *generate_code_return(char *str);
    char *generate_code_activate(char *str);
    char *generate_code_activate_refd(char *str);
    char *generate_code_deactivate(char *str);
    char *generate_code_send(char *str);
918
    char *generate_code_call(char *str, char*& def_glob_vars, char*& src_glob_vars);
Elemer Lelik's avatar
Elemer Lelik committed
919
920
921
922
923
924
925
926
927
928
929
930
931
    char *generate_code_reply(char *str);
    char *generate_code_raise(char *str);
    char *generate_code_portop(char *str, const char *opname);
    char *generate_code_startcomp(char *str);
    char *generate_code_startcomp_refd(char *str);
    char *generate_code_compop(char *str, const char *opname);
    char *generate_code_configop(char *str, const char *opname);
    char *generate_code_starttimer(char *str);
    char *generate_code_stoptimer(char *str);
    char *generate_code_setverdict(char *str);
    char *generate_code_action(char *str);
    char *generate_code_testcaseinst(char *str);
    char *generate_code_execute_refd(char *str);
932
    char* generate_code_update(char *str, char*& def_glob_vars, char*& src_glob_vars);
933
    char* generate_code_setstate(char *str);
934
    char* generate_code_setencode(char* str);
935
    char* generate_code_raise_oop(char* str);
Elemer Lelik's avatar
Elemer Lelik committed
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
    /** used for receive, check-receive, trigger */
    void generate_code_expr_receive(expression_struct *expr,
      const char *opname);
    /** used for getcall, check-getcall */
    void generate_code_expr_getcall(expression_struct *expr,
      const char *opname);
    /** used for getreply, check-getreply */
    void generate_code_expr_getreply(expression_struct *expr,
      const char *opname);
    /** used for catch, check-catch */
    void generate_code_expr_catch(expression_struct *expr);
    void generate_code_expr_check(expression_struct *expr);
    void generate_code_expr_done(expression_struct *expr);
    void generate_code_expr_killed(expression_struct *expr);
    void generate_code_expr_timeout(expression_struct *expr);
    /** Generates the C++ equivalent of \a port_op.s.sendpar into \a expr.
     *  When \a sendpar contains a simple specific value the value -> template
     * conversion is eliminated for better run-time performance. */
    void generate_code_expr_sendpar(expression_struct *expr);
    void generate_code_expr_fromclause(expression_struct *expr);
    void generate_code_expr_senderredirect(expression_struct *expr);
957
958
    void generate_code_expr_timestamp_redirect(expression_struct* expr,
      bool outgoing);
Elemer Lelik's avatar
Elemer Lelik committed
959
960
961
962
963
964
    /** Creates the string equivalent of port reference \a p_ref and
     *  appends it to \a expr->expr. Used in configuration operations
     *  when the component type cannot be determined from the
     *  component reference. */
    static void generate_code_portref(expression_struct *expr,
      Reference *p_ref);
Elemer Lelik's avatar
Elemer Lelik committed
965
    char* generate_code_int2enum(char* str);
Elemer Lelik's avatar
Elemer Lelik committed
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
  };

  /**
   * Class to store a VariableAssignment or TemplateAssignment.
   * Class is entirely unrelated to Common::Assignment and Asn::Assignment.
   */
  class Assignment : public Node, public Location {
  public:
    enum asstype_t {
      ASS_UNKNOWN,  ///< unknown assignment
      ASS_VAR,      ///< variable assignment
      ASS_TEMPLATE, ///< template assignment
      ASS_ERROR     ///< erroneous
    };

  private:
    asstype_t asstype;
    Reference *ref; ///< reference to the "left hand side"
    union {
      Value    *val;   ///< RHS for a variable assignment
      Template *templ; ///< RHS for a template assignment
    };
    /** true if the LHS is mentioned in the RHS */
    bool self_ref;
    /** template restriction on ref, set in chk() for faster code generation */
    template_restriction_t template_restriction;
    /** set in chk(), used by code generation */
    bool gen_restriction_check;
994
    bool in_constructor;
Elemer Lelik's avatar
Elemer Lelik committed
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007

    Assignment(const Assignment& p);
    Assignment& operator=(const Assignment& p);
  public:
    /** Creates a new template assignment. */
    Assignment(Reference *p_ref, Template *p_templ);
    /** Creates a new variable assignment. */
    Assignment(Reference *p_ref, Value *p_val);
    virtual ~Assignment();
    virtual Assignment *clone() const;
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    virtual void dump(unsigned int level) const;
1008
    void set_in_contructor() { in_constructor = true; }
Elemer Lelik's avatar
Elemer Lelik committed
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
  private:
    void chk_unknown_ass();
    void chk_var_ass();
    void chk_template_ass();
    void chk_template_restriction();
  public:
    void chk();
    /** Sets the code section selector of all embedded values and templates
     * to \a p_code_section. */
    void set_code_section(GovernedSimple::code_section_t p_code_section);
    char *generate_code(char *str);
  };

  /**
   * Class to store a ParamAssignment.
   */
  class ParamAssignment : public Node, public Location {
  private:
    Identifier *id;
    Reference *ref;
1029
1030
1031
1032
1033
1034
1035
    /** indicates whether the redirected parameter should be decoded */
    bool decoded;
    /** encoding format for decoded universal charstring parameter redirects */
    Value* str_enc;
    /** pointer to the type the redirected parameter is decoded into, if the
      * '@decoded' modifier is used (not owned) */
    Type* dec_type;
Elemer Lelik's avatar
Elemer Lelik committed
1036
1037
1038
1039

    ParamAssignment(const ParamAssignment& p);
    ParamAssignment& operator=(const ParamAssignment& p);
  public:
1040
1041
    ParamAssignment(Identifier *p_id, Reference *p_ref, bool p_decoded,
      Value* p_str_enc);
Elemer Lelik's avatar
Elemer Lelik committed
1042
1043
1044
1045
1046
1047
1048
    virtual ~ParamAssignment();
    virtual ParamAssignment* clone() const;
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    const Identifier& get_id() const { return *id; }
    Reference *get_ref() const;
    Reference *steal_ref();
1049
1050
1051
1052
1053
    bool is_decoded() const { return decoded; }
    Value* get_str_enc() const;
    Value* steal_str_enc();
    void set_dec_type(Type* p_dec_type) { dec_type = p_dec_type; }
    Type* get_dec_type() const { return dec_type; }
Elemer Lelik's avatar
Elemer Lelik committed
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
  };

  /**
   * Class to store a ParamAssignmentList
   */
  class ParamAssignments : public Node {
  private:
    vector<ParamAssignment> parasss;

    ParamAssignments(const ParamAssignments& p);
    ParamAssignments& operator=(const ParamAssignments& p);
  public:
    ParamAssignments() : Node() { }
    virtual ~ParamAssignments();
    virtual ParamAssignments* clone() const;
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    void add_parass(ParamAssignment *p_parass);
    size_t get_nof_parasss() const { return parasss.size(); }
    ParamAssignment *get_parass_byIndex(size_t p_i) const
      { return parasss[p_i]; }
  };

  /**
   * Class to represent a variable or notused-symbol in
   * ParamAssignmentList of port redirect stuff.
   */
  class VariableEntry : public Node, public Location {
  private:
    Reference *ref; /**< varref or notused if NULL. */
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
    /** indicates whether the redirected parameter should be decoded */
    bool decoded;
    /** encoding format for decoded universal charstring parameter redirects
      * (is only set when the AssignmentList is converted to a VariableList) */
    Value* str_enc;
    /** pointer to the type the redirected parameter is decoded into, if the
      * '@decoded' modifier is used
      * (is only set when the AssignmentList is converted to a VariableList,
      * not owned) */
    Type* dec_type;
Elemer Lelik's avatar
Elemer Lelik committed
1094
1095
1096
1097
1098

    VariableEntry(const VariableEntry& p);
    VariableEntry& operator=(const VariableEntry& p);
  public:
    /** Creates a notused entry */
1099
    VariableEntry() : Node(), Location(), ref(0), decoded(false), str_enc(NULL), dec_type(NULL) { }
Elemer Lelik's avatar
Elemer Lelik committed
1100
    VariableEntry(Reference *p_ref);
1101
    VariableEntry(Reference* p_ref, bool p_decoded, Value* p_str_enc, Type* p_dec_type);
Elemer Lelik's avatar
Elemer Lelik committed
1102
1103
1104
1105
1106
    virtual ~VariableEntry();
    virtual VariableEntry* clone() const;
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    Reference *get_ref() const { return ref; }
1107
1108
1109
    bool is_decoded() const { return decoded; }
    Value* get_str_enc() const { return str_enc; }
    Type* get_dec_type() const { return dec_type; }
Elemer Lelik's avatar
Elemer Lelik committed
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
  };

  /**
   * Class to store a VariableEntries
   */
  class VariableEntries : public Node {
  private:
    vector<VariableEntry> ves;

    VariableEntries(const VariableEntries& p);
    VariableEntries& operator=(const VariableEntries& p);
  public:
    VariableEntries() : Node() { }
    virtual ~VariableEntries();
    virtual VariableEntries* clone() const;
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    void add_ve(VariableEntry *p_ve);
    size_t get_nof_ves() const { return ves.size(); }
    VariableEntry *get_ve_byIndex(size_t p_i) const { return ves[p_i]; }
  };

  /**
   * Class to represent ParamAssignmentList in a param redirect of
   * getcall/getreply port operation.
   */
  class ParamRedirect : public Node, public Location {
  public:
    enum parredirtype_t {
      P_ASS, /**< AssignmentList */
      P_VAR /**< VariableList */
    };
  private:
    parredirtype_t parredirtype;
    union {
      ParamAssignments *parasss;
      VariableEntries *ves;
    };

    ParamRedirect(const ParamRedirect& p);
    ParamRedirect& operator=(const ParamRedirect& p);
  public:
    ParamRedirect(ParamAssignments *p_parasss);
    ParamRedirect(VariableEntries *p_ves);
    virtual ~ParamRedirect();
    virtual ParamRedirect* clone() const;
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    /** Performs some trivial checks on the variable references.
     * Used when the signature cannot be determined in a getcall or getreply
     * operation because of an error. */
    void chk_erroneous();
    /** Performs the checks on the param redirect clause. Parameter \a p_sig
     * points to the respective signature. Flag \a is_out is true if the
     * redirect belongs to a getreply operation (i.e. it may refer to out/inout
     * parameters) and false in case of getcall. */
    void chk(Type *p_sig, bool is_out);
  private:
    /** Helper function for \a chk(). Used when AssignmentList is selected.
     * If the redirect is correct it converts the AssignmentList to an
     * equivalent VariableList for easier code generation. */
    void chk_parasss(Type *p_sig, SignatureParamList *p_parlist, bool is_out);
    /** Helper function for \a chk(). Used when VariableList is selected. */
    void chk_ves(Type *p_sig, SignatureParamList *p_parlist, bool is_out);
    /** Checks whether the reference \a p_ref points to a variable of type
     * \a p_type. */
    static void chk_variable_ref(Reference *p_ref, Type *p_type);
  public:
    /** Sets the code section selector of all embedded values and templates
     * to \a p_code_section. */
    void set_code_section(GovernedSimple::code_section_t p_code_section);
1181
1182
    void generate_code(expression_struct_t *expr, TemplateInstance* matched_ti,
      bool is_out);
1183
1184
1185
    /** generates a new redirect class, inherited from the signature type's
      * original redirect class, which extends its functionality to also
      * decode the redirected parameters that have the '@decoded' modifier */
1186
1187
    char* generate_code_decoded(char* str, TemplateInstance* matched_ti,
      const char* tmp_id, bool is_out);
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
    /** returns true if at least one of the parameter redirects has the 
      * '@decoded' modifier */
    bool has_decoded_modifier() const;
  };
  
  /** 
    * Class for storing a single element of a value redirect
    * Each of these elements can be:
    * - a lone variable reference (in this case the whole value is redirected to
    *   the referenced variable), or
    * - the assignment of a field or a field's sub-reference to a variable
    *   (in this case one of the value's fields, or a sub-reference of one of the
    *   fields is redirected to the referenced variable; this can only happen if
    *   the value is a record or set).
    */
  class SingleValueRedirect : public Node, public Location {    
  private:
    /** reference to the variable the value is redirected to */
    Reference* var_ref;
    /** indicates which part (record field or array element) of the value is 
      * redirected (optional) */
    FieldOrArrayRefs* subrefs;
    /** indicates whether the redirected field or element should be decoded 
      * (only used if subrefs is not null) */
    bool decoded;
    /** encoding format for decoded universal charstring value redirects
      * (only used if subrefs is not null and decoded is true) */
    Value* str_enc;
    /** pointer to the type the redirected field or element is decoded into
      * (only used if subrefs is not null and decoded is true), not owned*/
    Type* dec_type;
    
    SingleValueRedirect(const SingleValueRedirect&);
    SingleValueRedirect& operator=(const SingleValueRedirect&);
  public:
    SingleValueRedirect(Reference* p_var_ref);
    SingleValueRedirect(Reference* p_var_ref, FieldOrArrayRefs* p_subrefs,
      bool p_decoded, Value* p_str_enc);
    virtual ~SingleValueRedirect();
    virtual SingleValueRedirect* clone() const;
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    Reference *get_var_ref() const { return var_ref; }
    FieldOrArrayRefs *get_subrefs() const { return subrefs; }
    bool is_decoded() const { return decoded; }
    Value* get_str_enc() const { return str_enc; }
    void set_dec_type(Type* p_dec_type) { dec_type = p_dec_type; }
    Type* get_dec_type() const { return dec_type; }
  };
  
  /**
    * Class for storing a value redirect
    */
  class ValueRedirect : public Node, public Location {
    /** list of single value redirect elements */
    vector<SingleValueRedirect> v;
    /** pointer to the type of the redirected value, not owned */
    Type* value_type;
1246
1247
1248
    /** indicates whether the value redirect is restricted to only one value of
      * type 'verdicttype' */
    bool verdict_only;
1249
1250
1251
1252
    
    ValueRedirect(const ValueRedirect&);
    ValueRedirect& operator=(const ValueRedirect&);
  public:
1253
    ValueRedirect(): v(), value_type(NULL), verdict_only(false) { }
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
    virtual ~ValueRedirect();
    virtual ValueRedirect* clone() const;
    virtual void set_my_scope(Scope* p_scope);
    virtual void set_fullname(const string& p_fullname);
    void set_code_section(GovernedSimple::code_section_t p_code_section);
    void add(SingleValueRedirect* ptr);
    /** Attempts to identify the type of the redirected value. Only those single
      * redirects are checked, which redirect the whole value, not just a field.
      * If multiple whole-value-redirects of separate types are found, then an
      * error is displayed. */
    Type* get_type() const;
1265
1266
    /** Checks Runtime1 restrictions and returns false if they are not met. */
    bool chk_RT1_restrictions() const;
1267
1268
1269
1270
    /** Performs semantic analysis on the value redirect without knowing the
      * type of the redirected value. Called when the value's type cannot be
      * determined or is erroneous. */
    void chk_erroneous();
1271
1272
1273
1274
    /** Performs the full semantic analysis on the value redirect.
      * Only used by the 'done' statement, when it can only redirect a value of
      * type 'verdicttype'. */
    void chk_verdict_only();
1275
1276
1277
1278
1279
1280
    /** Performs the full semantic analysis on the value redirect.
      * @param p_type the type of the redirected value */
    void chk(Type* p_type);
    /** Generates code for the value redirect in the specified expression
      * structure. A new class is generated for every value redirect, which
      * handles the redirecting.
1281
      * @param matched_ti the template instance used for matching the redirected
1282
1283
      * value (if NULL, then the template instance is an 'any value' template) */
    void generate_code(expression_struct* expr, TemplateInstance* matched_ti);
1284
1285
1286
    /** returns true if at least one of the value redirects has the 
      * '@decoded' modifier*/
    bool has_decoded_modifier() const;
Elemer Lelik's avatar
Elemer Lelik committed
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
  };

  /**
   * Class to represent a LogArgument.
   */
  class LogArgument : public Node, public Location {
  public:
    enum logargtype_t {
      L_UNDEF, /**< undefined (set during parsing) */
      L_ERROR, /**< erroneous */
      L_TI, /**< template instance */
      L_VAL, /**< literal value or expression */
      L_MATCH,  /**< match expression */
      L_MACRO, /**< macro value (%something) */
      L_REF, /**< reference */
      L_STR /**< literal character string */
    };

  private:
    logargtype_t logargtype;
    union {
      TemplateInstance *ti; ///< used by L_UNDEF and L_TI
      Value *val;           ///< used by L_VAL, L_MATCH, L_MACRO
1310
      Reference *ref;        ///< used by L_REF
Elemer Lelik's avatar
Elemer Lelik committed
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
      string *cstr;         ///< used by L_STR
    };

    LogArgument(const LogArgument& p);
    LogArgument& operator=(const LogArgument& p);
  public:
    LogArgument(TemplateInstance *p_ti);
    virtual ~LogArgument();
    virtual LogArgument *clone() const;
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    logargtype_t get_type() const { return logargtype; }
    const string&     get_str() const;
    Value            *get_val() const;
1325
    Reference        *get_ref() const;
Elemer Lelik's avatar
Elemer Lelik committed
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
    TemplateInstance *get_ti () const;
    /** Appends the string \a p_str to \a cstr. Applicable only if
     * \a logargtype is L_STR. */
    void append_str(const string& p_str);
    void chk();
    virtual void dump(unsigned int level) const;
  private:
    void chk_ref();
    void chk_val();
  public:
    /** Sets the code section selector of all embedded values and
     *  templates to \a p_code_section. */
    void set_code_section(GovernedSimple::code_section_t p_code_section);
    char *generate_code_log(char *str);
    void chk_recursions(ReferenceChain& refch);
    bool has_single_expr();
    void generate_code_expr(expression_struct *expr);
  };

  /**
   * Class to represent LogArgumentList.
   */
  class LogArguments : public Node {
  private:
    vector<LogArgument> logargs;

    LogArguments(const LogArguments& p);
    LogArguments& operator=(const LogArguments& p);
  public:
    LogArguments() : Node() { }
    virtual ~LogArguments();
    virtual LogArguments *clone() const;
    void add_logarg(LogArgument *p_logarg);
    size_t get_nof_logargs() const { return logargs.size(); }
    LogArgument *get_logarg_byIndex(size_t p_i) const { return logargs[p_i]; }
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    void chk();
    /** Joins adjacent strings into one LogArgument for more efficient
     * code generation. */
    void join_strings();
    /** Sets the code section selector of all embedded values and
     *  templates to \a p_code_section. */
    void set_code_section(GovernedSimple::code_section_t p_code_section);
    char *generate_code(char *str);
    void chk_recursions(ReferenceChain& refch);
    bool has_single_expr();
    void generate_code_expr(expression_struct *expr);
  };

  /**
   * Class to represent an if-clause: the condition and the statement
   * block. Note that the else block is kept by Statement::if_stmt.
   */
  class IfClause : public Node, public Location {
  private:
    Value *expr; /**< conditional expression */
    StatementBlock *block;

    IfClause(const IfClause& p);
    IfClause& operator=(const IfClause& p);
  public:
    IfClause(Value *p_expr, StatementBlock *p_block);
    virtual ~IfClause();
    virtual IfClause *clone() const;
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    Value *get_expr() const { return expr; }
    StatementBlock *get_block() const { return block; }
    /* checking functions */
    bool has_receiving_stmt() const;
    void chk(bool& unreach);
    /** Sets the code section selector of all embedded values and
     *  templates to \a p_code_section. */
    void set_code_section(GovernedSimple::code_section_t p_code_section);
1401
1402
    char* generate_code(char *str, char*& def_glob_vars, char*& src_glob_vars,
      size_t& blockcount, bool& unreach, bool& eachfalse);
Elemer Lelik's avatar
Elemer Lelik committed
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
    void ilt_generate_code(ILT *ilt, const char *end_label, bool& unreach);

    /** Needed by implicit omit. Pushes attrib path down to definitions
     */
    virtual void set_parent_path(WithAttribPath* p_path);
    virtual void dump(unsigned int level) const;
  };

  /**
   * Class to represent IfClauseList, a chain of if-else-if-else-if
   */
  class IfClauses : public Node {
  private:
    vector<IfClause> ics;

    IfClauses(const IfClauses& p);
    IfClauses& operator=(const IfClauses& p);
  public:
    IfClauses() : Node() { }
    virtual ~IfClauses();
    virtual IfClauses* clone() const;
    /// Called to add an "else-if" to a chain of "else-if"s
    void add_ic(IfClause *p_ic);
    /// Called to add the first "if" to a chain of "else-if"s
    void add_front_ic(IfClause *p_ic);
    size_t get_nof_ics() const {return ics.size();}
    IfClause *get_ic_byIndex(size_t p_i) const {return ics[p_i];}
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    void set_my_sb(StatementBlock *p_sb, size_t p_index);
    void set_my_def(Definition *p_def);
    void set_my_ags(AltGuards *p_ags);
    void set_my_laic_stmt(AltGuards *p_ags, Statement *p_loop_stmt);
    StatementBlock::returnstatus_t has_return(StatementBlock *elseblock) const;
    bool has_receiving_stmt() const;
    /* checking functions */
    void chk(bool& unreach);
    /** checks whether all embedded statements are allowed in an interleaved
     * construct */
    void chk_allowed_interleave();
    /** Sets the code section selector of all embedded values and
     *  templates to \a p_code_section. */
    void set_code_section(GovernedSimple::code_section_t p_code_section);
1446
1447
    char* generate_code(char *str, char*& def_glob_vars, char*& src_glob_vars,
      size_t& blockcount, bool& unreach, bool& eachfalse);
Elemer Lelik's avatar
Elemer Lelik committed
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
    void ilt_generate_code(ILT *ilt, const char *end_label, bool& unreach);

    /** Needed by implicit omit. Pushes attrib path down to definitions
     */
    virtual void set_parent_path(WithAttribPath* p_path);
    virtual void dump(unsigned int level) const;
  };

  /**
   * Class to represent a select-case: the template instance list and
   * the statement block.
   */
  class SelectCase : public Node, public Location {
  private:
    TemplateInstances *tis;
    StatementBlock *block;

    SelectCase(const SelectCase& p);
    SelectCase& operator=(const SelectCase& p);
  public:
    /** tis==0 means "else" case */
    SelectCase(TemplateInstances *p_tis, StatementBlock *p_block);
    virtual ~SelectCase();
    virtual SelectCase* clone() const;
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    TemplateInstances* get_tis() const { return tis; }
    StatementBlock *get_block() const { return block; }
    /* checking functions */
    void chk(Type *p_gov, bool& unreach);
    /** Sets the code section selector of all embedded values and
     *  templates to \a p_code_section. */
    void set_code_section(GovernedSimple::code_section_t p_code_section);
    char* generate_code_if(char *str, const char *tmp_prefix,
                           const char *expr_name, size_t idx, bool& unreach);
1483
1484
1485
1486
    char* generate_code_case(char *str, char*& def_glob_vars, char*& src_glob_vars,
      bool& else_branch, vector<const Int>& used_numbers);
    char* generate_code_stmt(char *str, char*& def_glob_vars, char*& src_glob_vars,
      const char *tmp_prefix, size_t idx, bool& unreach);
Elemer Lelik's avatar
Elemer Lelik committed
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
    void ilt_generate_code_stmt(ILT *ilt, const char *tmp_prefix,
                                size_t idx, bool& unreach);

    /** Needed by implicit omit. Pushes attrib path down to definitions
     */
    virtual void set_parent_path(WithAttribPath* p_path);
  };

  /**
   * Class to represent SelectCaseList.
   */
  class SelectCases : public Node {
  private:
    vector<SelectCase> scs;

    SelectCases(const SelectCases& p);
    SelectCases& operator=(const SelectCases& p);
  public:
    SelectCases() : Node() { }
    virtual ~SelectCases();
    virtual SelectCases* clone() const;
    void add_sc(SelectCase *p_sc);
    size_t get_nof_scs() const {return scs.size();}
    SelectCase *get_sc_byIndex(size_t p_i) const {return scs[p_i];}
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    void set_my_sb(StatementBlock *p_sb, size_t p_index);
    void set_my_def(Definition *p_def);
    void set_my_ags(AltGuards *p_ags);
    void set_my_laic_stmt(AltGuards *p_ags, Statement *p_loop_stmt);
    StatementBlock::returnstatus_t has_return() const;
    bool has_receiving_stmt() const;
1519
    bool can_generate_switch() const;
Elemer Lelik's avatar
Elemer Lelik committed
1520
1521
1522
1523
1524
1525
1526
1527
1528
    /* checking functions */
    /** p_gov is the governor type of select expression */
    void chk(Type *p_gov);
    /** checks whether all embedded statements are allowed in an interleaved
     * construct */
    void chk_allowed_interleave();
    /** Sets the code section selector of all embedded values and
     *  templates to \a p_code_section. */
    void set_code_section(GovernedSimple::code_section_t p_code_section);
1529
1530
    char *generate_code(char *str, char*& def_glob_vars, char*& src_glob_vars,
      const char *tmp_prefix, const char *expr_name);   
Elemer Lelik's avatar
Elemer Lelik committed
1531
    void ilt_generate_code(ILT *ilt, const char *tmp_prefix,
1532
1533
1534
1535
                           const char *expr_init, const char *head_expr,
                           const char *expr_name);
    /** generates code with switch c++ statement only for integer 
     *  compatible types*/
1536
    char *generate_code_switch(char *str, char*& def_glob_vars, char*& src_glob_vars, const char *expr_name);
1537
1538
    void ilt_generate_code_switch(ILT *ilt, const char *expr_init, const char *head_expr, const char *expr_name);
    
Elemer Lelik's avatar
Elemer Lelik committed
1539
1540
1541
1542
1543

    /** Needed by implicit omit. Pushes attrib path down to definitions
     */
    virtual void set_parent_path(WithAttribPath* p_path);
  };
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
  
   /**
   * Class to represent a select-union branch: the identifier list and
   * the statement block.
   */
  class SelectUnion : public Node, public Location {
  private:
    vector<Identifier> ids;
    StatementBlock *block;

    SelectUnion(const SelectUnion& p);
    SelectUnion& operator=(const SelectUnion& p);
  public:
    /** ids.empty() == true means "else" case */
    SelectUnion(StatementBlock *p_block);
    virtual ~SelectUnion();
    virtual SelectUnion* clone() const;
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    const vector<Identifier>& get_ids() const { return ids; }
    Identifier* get_id_byIndex(size_t index) const { return ids[index]; }
    StatementBlock *get_block() const { return block; }
    void add_id(Identifier* id);
    /* checking functions */
1568
    void chk();
1569
    void set_code_section(GovernedSimple::code_section_t p_code_section);
1570
1571
    char* generate_code_case(char *str, char*& def_glob_vars, char*& src_glob_vars,
      const char *type_name, bool &else_branch);
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602

    /** Needed by implicit omit. Pushes attrib path down to definitions
     */
    virtual void set_parent_path(WithAttribPath* p_path);
  };

  /**
   * Class to represent SelectUnions.
   */
  class SelectUnions : public Node {
  private:
    vector<SelectUnion> sus;

    SelectUnions(const SelectUnions& p);
    SelectUnions& operator=(const SelectUnions& p);
  public:
    SelectUnions() : Node() { }
    virtual ~SelectUnions();
    virtual SelectUnions* clone() const;
    void add_su(SelectUnion *p_su);
    size_t get_nof_sus() const {return sus.size();}
    SelectUnion *get_su_byIndex(size_t p_i) const {return sus[p_i];}
    virtual void set_my_scope(Scope *p_scope);
    virtual void set_fullname(const string& p_fullname);
    void set_my_sb(StatementBlock *p_sb, size_t p_index);
    void set_my_def(Definition *p_def);
    void set_my_ags(AltGuards *p_ags);
    void set_my_laic_stmt(AltGuards *p_ags, Statement *p_loop_stmt);
    StatementBlock::returnstatus_t has_return() const;
    bool has_receiving_stmt() const;
    /* checking functions */
1603
    void chk();
1604
1605
1606
1607
    /** checks whether all embedded statements are allowed in an interleaved
     * construct */
    void chk_allowed_interleave();
    void set_code_section(GovernedSimple::code_section_t p_code_section);
1608
1609
    char *generate_code(char *str, char*& def_glob_vars, char*& src_glob_vars,
      const char *type_name, const char* loc);
1610
1611
1612
1613
1614

    /** Needed by implicit omit. Pushes attrib path down to definitions
     */
    virtual void set_parent_path(WithAttribPath* p_path);
  };
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
  
  
  /**
   * Class to represent a select-class-case: the class type reference and
   * the statement block.
   */
  class SelectClassCase : public Node, public Location {
  private:
    Common::Type* type;
    StatementBlock* block;
    Common::Scope* my_scope;
    bool always_false;

    SelectClassCase(const SelectCase& p);
    SelectClassCase& operator=(const SelectCase& p);
  public:
    /** type == NULL means "else" case */
    SelectClassCase(Common::Type* p_type, StatementBlock* p_block);
    virtual ~SelectClassCase();
    virtual SelectClassCase* clone() const;
    virtual void set_my_scope(Scope* p_scope);
    virtual void set_fullname(const string& p_fullname);
    Common::Type* get_type() const { return type; }
    StatementBlock* get_block() const { return block; }
    /* checking functions */
    void chk(ClassTypeBody* p_ref_class, bool& unreach);
    /** Sets the code section selector of all embedded values and
     *  templates to \a p_code_section. */
    void set_code_section(GovernedSimple::code_section_t p_code_section);
    char* generate_code_if(char* str, const char* tmp_prefix,
      const char* ref_str, size_t idx, bool& unreach);
    char* generate_code_stmt(char* str, char*& def_glob_vars, char*& src_glob_vars,
      const char* tmp_prefix, size_t idx, bool& unreach);
    void ilt_generate_code_stmt(ILT* ilt, const char* tmp_prefix,
      size_t idx, bool& unreach);

    /** Needed by implicit omit. Pushes attrib path down to definitions
     */
    virtual void set_parent_path(WithAttribPath* p_path);
  };

  /**
   * Class to represent a select class construct.
   */
  class SelectClassCases : public Node {
  private:
    vector<SelectClassCase> sccs;

    SelectClassCases(const SelectCases& p);
    SelectClassCases& operator=(const SelectCases& p);
  public:
    SelectClassCases() : Node() { }
    virtual ~SelectClassCases();
    virtual SelectClassCases* clone() const;
    void add_scc(SelectClassCase* p_scc);
    size_t get_nof_sccs() const { return sccs.size(); }
    SelectClassCase *get_scc_byIndex(size_t p_i) const { return sccs[p_i]; }
    virtual void set_my_scope(Scope* p_scope);
    virtual void set_fullname(const string& p_fullname);
    void set_my_sb(StatementBlock* p_sb, size_t p_index);
    void set_my_def(Definition* p_def);
    void set_my_ags(AltGuards* p_ags);
    void set_my_laic_stmt(AltGuards* p_ags, Statement* p_loop_stmt);
    StatementBlock::returnstatus_t has_return() const;
    bool has_receiving_stmt() const;
    /* checking functions */
    /** p_ref_class is the class of the select reference */
    void chk(ClassTypeBody* p_ref_class);
    /** checks whether all embedded statements are allowed in an interleaved
     * construct */
    void chk_allowed_interleave();
    /** Sets the code section selector of all embedded values and
     *  templates to \a p_code_section. */
    void set_code_section(GovernedSimple::code_section_t p_code_section);
    char* generate_code(char* str, char*& def_glob_vars, char*& src_glob_vars,
      const char* tmp_prefix, const char* ref_str);   
    void ilt_generate_code(ILT* ilt, const char* tmp_prefix, const char* ref_str);
    

    /** Needed by implicit omit. Pushes attrib path down to definitions
     */
    virtual void set_parent_path(WithAttribPath* p_path);
  };
1698

Elemer Lelik's avatar
Elemer Lelik committed
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715

  /**
   * Class to represent an alt guard.
   */
  class AltGuard : public Node, public Location {
  public:
    enum altguardtype_t {
      AG_OP,
      AG_REF,
      AG_INVOKE,
      AG_ELSE
    };

  private:
    altguardtype_t altguardtype;
    Value *expr; /**< conditional expression */
    union {
1716
      Reference *ref;
Elemer Lelik's avatar
Elemer Lelik committed
1717
1718
1719