Commit | Line | Data |
---|---|---|
d44e3c4f | 1 | /****************************************************************************** |
2 | * Copyright (c) 2000-2016 Ericsson Telecom AB | |
3 | * All rights reserved. This program and the accompanying materials | |
4 | * are made available under the terms of the Eclipse Public License v1.0 | |
5 | * which accompanies this distribution, and is available at | |
6 | * http://www.eclipse.org/legal/epl-v10.html | |
7 | * | |
8 | * Contributors: | |
9 | * Baji, Laszlo | |
10 | * Balasko, Jeno | |
11 | * Baranyi, Botond | |
12 | * Delic, Adam | |
13 | * Kovacs, Ferenc | |
14 | * Raduly, Csaba | |
15 | * Szabados, Kristof | |
16 | * Zalanyi, Balazs Andor | |
17 | * Pandi, Krisztian | |
18 | * | |
19 | ******************************************************************************/ | |
970ed795 EL |
20 | #ifndef _Ttcn_AST_HH |
21 | #define _Ttcn_AST_HH | |
22 | ||
23 | #include "../AST.hh" | |
24 | ||
25 | namespace Common { | |
26 | class CodeGenHelper; | |
27 | } | |
28 | ||
29 | /** | |
30 | * This namespace contains classes unique to TTCN-3 and some specializations | |
31 | * of classes from Common. | |
32 | */ | |
33 | namespace Ttcn { | |
34 | ||
35 | /** | |
36 | * \addtogroup AST | |
37 | * | |
38 | * @{ | |
39 | */ | |
40 | ||
41 | using namespace Common; | |
42 | ||
43 | class Module; | |
44 | class Definition; | |
45 | class FriendMod; | |
46 | class Imports; | |
47 | class ImpMod; | |
48 | class ActualPar; | |
49 | class ActualParList; | |
50 | class FormalParList; | |
51 | class ParsedActualParameters; | |
52 | class Template; | |
53 | class TemplateInstance; | |
54 | class TemplateInstances; | |
55 | class ArrayDimensions; | |
56 | class Timer; | |
57 | class StatementBlock; | |
58 | class AltGuards; | |
59 | class ILT; | |
60 | class Group; | |
61 | class WithAttribPath; | |
62 | class ErrorBehaviorList; | |
63 | class ErroneousAttributes; | |
64 | class ErroneousAttributeSpec; | |
65 | class PrintingType; | |
66 | ||
67 | /** Class to represent an actual parameter */ | |
68 | class ActualPar : public Node { | |
69 | public: | |
70 | enum ap_selection_t { | |
71 | AP_ERROR, ///< erroneous | |
72 | AP_VALUE, ///< "in" value parameter | |
73 | AP_TEMPLATE, ///< "in" template parameter | |
74 | AP_REF, ///< out/inout value or template parameter | |
75 | AP_DEFAULT ///< created from the default value of a formal parameter | |
76 | }; | |
77 | private: | |
78 | ap_selection_t selection; | |
79 | union { | |
80 | Value *val; ///< Value for AP_VALUE. Owned by ActualPar | |
81 | TemplateInstance *temp; ///< %Template for AP_TEMPLATE. Owned by ActualPar | |
82 | Ref_base *ref; ///< %Reference for AP_REF. Owned by ActualPar | |
83 | ActualPar *act; ///< For AP_DEFAULT. \b Not owned by ActualPar | |
84 | }; | |
85 | Scope *my_scope; ///< %Scope. Not owned | |
86 | /** tells what runtime template restriction check to generate, | |
87 | * TR_NONE means that no check is needed because it could be determined | |
88 | * in compile time */ | |
89 | template_restriction_t gen_restriction_check; | |
90 | /** if this is an actual template parameter of an external function add | |
91 | * runtime checks for out and inout parameters after the call */ | |
92 | template_restriction_t gen_post_restriction_check; | |
93 | private: | |
94 | /** Copy constructor not implemented */ | |
95 | ActualPar(const ActualPar& p); | |
96 | /** %Assignment disabled */ | |
97 | ActualPar& operator=(const ActualPar& p); | |
98 | public: | |
99 | /// Constructor for an erroneous object (fallback) | |
100 | ActualPar() | |
101 | : Node(), selection(AP_ERROR), my_scope(0), | |
102 | gen_restriction_check(TR_NONE), gen_post_restriction_check(TR_NONE) {} | |
103 | /// Actual par for an in value parameter | |
104 | ActualPar(Value *v); | |
105 | /// Actual par for an in template parameter | |
106 | ActualPar(TemplateInstance *t); | |
107 | /// Actual par for an {out or inout} {value or template} parameter | |
108 | ActualPar(Ref_base *r); | |
109 | /// Created from the default value of a formal par, at the call site, | |
110 | /// | |
111 | ActualPar(ActualPar *a); | |
112 | virtual ~ActualPar(); | |
113 | virtual ActualPar *clone() const; | |
114 | virtual void set_fullname(const string& p_fullname); | |
115 | virtual void set_my_scope(Scope *p_scope); | |
116 | bool is_erroneous() const { return selection == AP_ERROR; } | |
117 | ap_selection_t get_selection() const { return selection; } | |
118 | Value *get_Value() const; | |
119 | TemplateInstance *get_TemplateInstance() const; | |
120 | Ref_base *get_Ref() const; | |
121 | ActualPar *get_ActualPar() const; | |
122 | /** Checks the embedded recursions within the value or template instance. */ | |
123 | void chk_recursions(ReferenceChain& refch); | |
124 | /** Returns whether the actual parameter can be represented by an in-line | |
125 | * C++ expression. */ | |
126 | bool has_single_expr(); | |
127 | void set_code_section(GovernedSimple::code_section_t p_code_section); | |
128 | /** Generates the C++ equivalent of \a this into \a expr. | |
129 | * Flag \a copy_needed indicates whether to add an extra copy constructor | |
130 | * call if \a this contains a referenced value or template to avoid | |
131 | * aliasing problems with other out/inout parameters. */ | |
132 | void generate_code(expression_struct *expr, bool copy_needed, bool lazy_param=false, bool used_as_lvalue=false) const; | |
133 | /** Appends the initialization sequence of all (directly or indirectly) | |
51fa56b9 | 134 | * referred non-parameterized templates and the default values of all |
135 | * parameterized templates to \a str and returns the resulting string. | |
136 | * Only objects belonging to module \a usage_mod are initialized. */ | |
137 | char *rearrange_init_code(char *str, Common::Module* usage_mod); | |
138 | char *rearrange_init_code_defval(char *str, Common::Module* usage_mod); | |
970ed795 EL |
139 | /** Appends the string representation of the actual parameter to \a str. */ |
140 | void append_stringRepr(string& str) const; | |
141 | virtual void dump(unsigned level) const; | |
142 | void set_gen_restriction_check(template_restriction_t tr) | |
143 | { gen_restriction_check = tr; } | |
144 | template_restriction_t get_gen_restriction_check() | |
145 | { return gen_restriction_check; } | |
146 | void set_gen_post_restriction_check( | |
147 | template_restriction_t p_gen_post_restriction_check) | |
148 | { gen_post_restriction_check = p_gen_post_restriction_check; } | |
149 | }; | |
150 | ||
151 | /// A collection of actual parameters (parameter list) | |
152 | class ActualParList : public Node { | |
153 | vector<ActualPar> params; | |
154 | public: | |
155 | ActualParList(): Node(), params() { } | |
156 | ActualParList(const ActualParList& p); | |
157 | ~ActualParList(); | |
158 | ActualParList* clone() const; | |
159 | virtual void set_fullname(const string& p_fullname); | |
160 | virtual void set_my_scope(Scope *p_scope); | |
161 | size_t get_nof_pars() const { return params.size(); } | |
162 | void add(ActualPar* p) { params.add(p); } | |
163 | ActualPar* get_par(size_t i) const { return params[i]; } | |
164 | /** Checks the embedded recursions within the values and template | |
165 | * instances of actual parameters. */ | |
166 | void chk_recursions(ReferenceChain& refch); | |
167 | /** Generates the C++ equivalent of the actual parameter list without | |
168 | * considering any aliasing between variables and 'in' parameters. */ | |
169 | void generate_code_noalias(expression_struct *expr, FormalParList *p_fpl); | |
170 | /** Generates the C++ equivalent of the actual parameter list considering | |
171 | * aliasing problems between the 'in' parameters and 'out'/'inout' | |
172 | * parameters as well as component variables seen by the called definition. | |
173 | * Argument \a p_fpl points to the formal parameter list of the referred | |
174 | * definition if it is known, otherwise it is NULL. Argument \a p_comptype | |
175 | * points to the component type identified by the 'runs on' clause of the | |
176 | * referred definition (if exists and relevant for alias analysis, | |
177 | * otherwise NULL). | |
178 | * When invoke() is used with FAT types: the special case of 'runs on self' | |
179 | * has the argument \a p_compself set to true and \a p_comptype is NULL, | |
180 | * but the component is 'self' or any compatible component. */ | |
181 | void generate_code_alias(expression_struct *expr, FormalParList *p_fpl, | |
182 | Type *p_comptype, bool p_compself); | |
183 | /** Walks through the parameter list and appends the initialization | |
184 | * sequence of all (directly or indirectly) referred non-parameterized | |
51fa56b9 | 185 | * templates and the default values of all parameterized templates to |
186 | * \a str and returns the resulting string. | |
187 | * Only objects belonging to module \a usage_mod are initialized. */ | |
188 | char *rearrange_init_code(char *str, Common::Module* usage_mod); | |
970ed795 EL |
189 | virtual void dump(unsigned level) const; |
190 | }; | |
191 | ||
192 | /** Helper class for the Ttcn::Reference */ | |
193 | class FieldOrArrayRef : public Node, public Location { | |
194 | public: | |
195 | enum reftype { FIELD_REF, ARRAY_REF }; | |
196 | private: | |
197 | reftype ref_type; ///< reference type | |
198 | /** The stored reference. Owned and destroyed by FieldOrArrayRef */ | |
199 | union { | |
200 | Identifier *id; ///< name of the field, used by FIELD_REF | |
201 | Value *arp; ///< value of the index, used by ARRAY_REF | |
202 | } u; | |
203 | /** Copy constructor for clone() only */ | |
204 | FieldOrArrayRef(const FieldOrArrayRef& p); | |
205 | /** %Assignment disabled */ | |
206 | FieldOrArrayRef& operator=(const FieldOrArrayRef& p); | |
207 | public: | |
208 | FieldOrArrayRef(Identifier *p_id); | |
209 | FieldOrArrayRef(Value *p_arp); | |
210 | ~FieldOrArrayRef(); | |
211 | virtual FieldOrArrayRef* clone() const; | |
212 | virtual void set_fullname(const string& p_fullname); | |
213 | virtual void set_my_scope(Scope *p_scope); | |
214 | reftype get_type() const { return ref_type; } | |
215 | /** Return the identifier. | |
216 | * @pre reftype is FIELD_REF, or else FATAL_ERROR */ | |
217 | const Identifier* get_id() const; | |
218 | /** Returns the value. | |
219 | * @pre reftype is ARRAY_REF, or else FATAL_ERROR */ | |
220 | Value* get_val() const; | |
221 | /** Appends the string representation of the sub-reference to \a str. */ | |
222 | void append_stringRepr(string& str) const; | |
3abe9331 | 223 | /** Sets the first letter in the name of the field to lowercase if it's an |
224 | * uppercase letter. | |
225 | * Used on open types (the name of their alternatives can be given with both | |
226 | * an uppercase or a lowercase first letter, and the generated code will need | |
227 | * to use the lowercase version). */ | |
228 | void set_field_name_to_lowercase(); | |
970ed795 EL |
229 | }; |
230 | ||
231 | /** A vector of FieldOrArrayRef objects */ | |
232 | class FieldOrArrayRefs : public Node { | |
233 | /** Element holder. This FieldOrArrayRefs object owns the elements | |
234 | * and will free them in the destructor. */ | |
235 | vector<FieldOrArrayRef> refs; | |
236 | /** Indicates whether the last array index refers to an element of a | |
237 | * string value. */ | |
238 | bool refs_str_element; | |
239 | public: | |
240 | FieldOrArrayRefs() : Node(), refs(), refs_str_element(false) { } | |
241 | FieldOrArrayRefs(const FieldOrArrayRefs& p); | |
242 | ~FieldOrArrayRefs(); | |
243 | FieldOrArrayRefs *clone() const; | |
244 | virtual void set_fullname(const string& p_fullname); | |
245 | virtual void set_my_scope(Scope *p_scope); | |
246 | void add(FieldOrArrayRef *p_ref) { refs.add(p_ref); } | |
247 | size_t get_nof_refs() const { return refs.size(); } | |
248 | FieldOrArrayRef* get_ref(size_t i) const { return refs[i]; } | |
249 | bool has_unfoldable_index() const; | |
250 | /** Removes (deletes) the first \a n field references. */ | |
251 | void remove_refs(size_t n); | |
252 | Identifier *remove_last_field(); | |
253 | /** Generates the C++ sub-expression that accesses | |
254 | * the given sub-references of definition \a ass. | |
255 | * @param nof_subrefs indicates the number of sub-references | |
256 | * to generate code from (UINT_MAX means all of them) */ | |
257 | void generate_code(expression_struct *expr, Common::Assignment *ass, size_t nof_subrefs = UINT_MAX); | |
258 | /** Appends the string representation of sub-references to \a str. */ | |
259 | void append_stringRepr(string &str) const; | |
260 | bool refers_to_string_element() const { return refs_str_element; } | |
261 | void set_string_element_ref() { refs_str_element = true; } | |
262 | void clear_string_element_ref() { refs_str_element = false; } | |
263 | }; | |
264 | ||
265 | /** | |
266 | * Base class for all TTCN-3 references. | |
267 | * Includes the common functionality for parameterized and non-parameterized | |
268 | * references (e.g. handling of field or array subreferences). | |
269 | */ | |
270 | class Ref_base : public Ref_simple { | |
271 | protected: // Ttcn::Reference and Ttcn::Ref_pard need access | |
272 | Identifier *modid; | |
273 | /** If id is a NULL pointer all components are stored in subrefs */ | |
274 | Identifier *id; | |
275 | FieldOrArrayRefs subrefs; | |
276 | /** Indicates whether the consistency of formal and actual parameter lists | |
277 | * has been verified. */ | |
278 | bool params_checked; | |
279 | bool usedInIsbound; | |
280 | Ref_base(const Ref_base& p); | |
281 | private: | |
282 | Ref_base& operator=(const Ref_base& p); | |
283 | public: | |
284 | /** Default constructor: sets \a modid and \a id to NULL. Used by | |
285 | * non-parameterized references only. It is automatically guessed whether | |
286 | * the first component of \a subrefs is a module id or not. */ | |
287 | Ref_base() : Ref_simple(), modid(0), id(0), subrefs(), params_checked(0) | |
288 | , usedInIsbound(false) {} | |
289 | Ref_base(Identifier *p_modid, Identifier *p_id); | |
290 | ~Ref_base(); | |
291 | virtual Ref_base *clone() const = 0; | |
292 | virtual void set_fullname(const string& p_fullname); | |
293 | virtual void set_my_scope(Scope *p_scope); | |
294 | /** Sets the scope of the base reference to \a p_scope. | |
295 | * The scope of array indices in \a subrefs remains unchanged. */ | |
296 | void set_base_scope(Scope *p_scope) { Ref_simple::set_my_scope(p_scope); } | |
297 | virtual bool getUsedInIsbound() {return usedInIsbound;} | |
298 | virtual void setUsedInIsbound() {usedInIsbound = true;} | |
299 | Setting *get_refd_setting(); | |
300 | FieldOrArrayRefs *get_subrefs(); | |
301 | /** Appends \a p_ref to the sub-references */ | |
302 | void add(FieldOrArrayRef *p_ref) { subrefs.add(p_ref); } | |
303 | virtual bool has_single_expr(); | |
304 | virtual void set_code_section( | |
305 | GovernedSimple::code_section_t p_code_section); | |
306 | /** Generates the C++ equivalent of the reference (including the parameter | |
307 | * list and sub-references) as an access to a constant resource. | |
308 | */ | |
309 | virtual void generate_code_const_ref(expression_struct_t *expr); | |
310 | }; | |
311 | ||
312 | /** | |
313 | * TTCN-3 reference without parameters. | |
314 | * Implements the automatic detection whether the first identifier is a | |
315 | * module name or not. | |
316 | */ | |
317 | class Reference : public Ref_base { | |
318 | ActualParList *parlist; | |
319 | public: | |
320 | Reference(Identifier *p_id); | |
321 | Reference(Identifier *p_modid, Identifier *p_id) | |
322 | : Ref_base(p_modid, p_id), parlist(0) { } | |
323 | ~Reference(); | |
324 | virtual Reference *clone() const; | |
325 | virtual string get_dispname(); | |
326 | virtual Common::Assignment *get_refd_assignment(bool check_parlist = true); | |
327 | virtual const Identifier* get_modid(); | |
328 | virtual const Identifier* get_id(); | |
329 | /** Checks whether \a this points to a variable or value parameter. | |
330 | * Returns the type of the respective variable or variable field or NULL | |
331 | * in case of error. */ | |
332 | Type *chk_variable_ref(); | |
333 | /** Checks if \a this points to a component. | |
334 | * Returns the type of the component if so or NULL in case of error. */ | |
335 | Type *chk_comptype_ref(); | |
336 | virtual bool has_single_expr(); | |
337 | virtual void generate_code(expression_struct_t *expr); | |
338 | /** Generates the C++ equivalent of port references within | |
339 | * connect/disconnect/map/unmap statements into \a expr. | |
340 | * Argument \a p_scope shall point to the scope of the statement. */ | |
341 | void generate_code_portref(expression_struct_t *expr, Scope *p_scope); | |
342 | virtual void generate_code_const_ref(expression_struct_t *expr); | |
343 | /** | |
344 | * Generates code for checking if the reference | |
345 | * and the referred objects are bound or not.*/ | |
346 | void generate_code_ispresentbound(expression_struct_t *expr, | |
347 | bool is_template, const bool isbound); | |
3f84031e | 348 | /** If the referenced object is a formal parameter, it is marked as used. */ |
349 | void refd_param_usage_found(); | |
970ed795 EL |
350 | private: |
351 | /** Detects whether the first identifier in subrefs is a module id */ | |
352 | void detect_modid(); | |
353 | }; | |
354 | ||
355 | /** | |
356 | * Parameterized TTCN-3 reference | |
357 | */ | |
358 | class Ref_pard : public Ref_base { | |
359 | /** "Processed" parameter list, after the semantic check. */ | |
360 | ActualParList parlist; | |
361 | /** "Raw" parameter list, before the semantic check. */ | |
362 | Ttcn::ParsedActualParameters *params; | |
363 | /** Used by generate_code_cached(). Stores the generated expression string, | |
364 | * so it doesn't get regenerated every time. */ | |
365 | char* expr_cache; | |
366 | /** Copy constructor. Private, used by Ref_pard::clone() only */ | |
367 | Ref_pard(const Ref_pard& p); | |
368 | /// %Assignment disabled | |
369 | Ref_pard& operator=(const Ref_pard& p); | |
370 | public: | |
371 | /** Constructor | |
372 | * \param p_modid the module in which it resides | |
373 | * \param p_id the identifier | |
374 | * \param p_params parameters. For a function, this is the list constructed | |
375 | * for the actual parameters. | |
376 | * */ | |
377 | Ref_pard(Identifier *p_modid, Identifier *p_id, | |
378 | ParsedActualParameters *p_params); | |
379 | ~Ref_pard(); | |
380 | virtual Ref_pard *clone() const; | |
381 | virtual void set_fullname(const string& p_fullname); | |
382 | virtual void set_my_scope(Scope *p_scope); | |
383 | string get_dispname(); | |
384 | virtual Common::Assignment *get_refd_assignment(bool check_parlist = true); | |
385 | virtual const Identifier *get_modid(); | |
386 | virtual const Identifier *get_id(); | |
387 | virtual ActualParList *get_parlist(); | |
388 | /** Checks whether \a this is a correct argument of an activate operation | |
389 | * or statement. The reference shall point to an altstep with proper | |
390 | * `runs on' clause and the actual parameters that are passed by reference | |
391 | * shall not point to local definitions. The function returns true if the | |
392 | * altstep reference is correct and false in case of any error. */ | |
393 | bool chk_activate_argument(); | |
394 | virtual bool has_single_expr(); | |
395 | virtual void set_code_section( | |
396 | GovernedSimple::code_section_t p_code_section); | |
397 | virtual void generate_code (expression_struct_t *expr); | |
398 | virtual void generate_code_const_ref(expression_struct_t *expr); | |
399 | ||
400 | /** Used when an 'all from' is called on a function or parametrised template, | |
401 | * generate_code would generate new temporaries for the function's parameters | |
402 | * each call. This method makes sure the same temporaries are used every time | |
403 | * the function is called in the generated code. | |
404 | * On the first run calls generate_code and stores its result (only expr.expr | |
405 | * is cached, since the preamble is only needed after the first call). | |
406 | * On further runs the cached expression is returned.*/ | |
407 | virtual void generate_code_cached (expression_struct_t *expr); | |
408 | }; | |
409 | ||
410 | /** | |
411 | * Class Ttcn::NameBridgingScope. | |
412 | * This scope unit is NOT A REAL SCOPE UNIT, | |
413 | * its only purpose is to serve as a bridge with a name between two real scope | |
414 | * units. All operations are transfered automatically. | |
415 | */ | |
416 | class NameBridgingScope : public Scope { | |
417 | virtual string get_scopeMacro_name() const; | |
418 | virtual NameBridgingScope* clone() const; | |
419 | virtual Common::Assignment* get_ass_bySRef(Ref_simple *p_ref); | |
420 | }; | |
421 | ||
422 | /** | |
423 | * Class Ttcn::RunsOnScope. | |
424 | * Implements the scoping rules for functions, altsteps and testcases that | |
425 | * have a 'runs on' clause. First looks for the definitions in the given | |
426 | * component type first then it searches in its parent scope. | |
427 | * Note: This scope unit cannot access the parent scope of the component type | |
428 | * (which is a module Definitions) unless the component type and the | |
429 | * 'runs on' clause is defined in the same module. | |
430 | */ | |
431 | class RunsOnScope : public Scope { | |
432 | /** Points to the component type. */ | |
433 | Type *component_type; | |
434 | /** Shortcut to the definitions within \a component_type. */ | |
435 | ComponentTypeBody *component_defs; | |
436 | ||
437 | /** Not implemented. Causes \a FATAL_ERROR. */ | |
438 | RunsOnScope(const RunsOnScope& p); | |
439 | /** %Assignment not implemented */ | |
440 | RunsOnScope& operator=(const RunsOnScope& p); | |
441 | public: | |
442 | RunsOnScope(Type *p_comptype); | |
443 | virtual RunsOnScope *clone() const; | |
444 | ||
445 | Type *get_component_type() const { return component_type; } | |
446 | /** Checks the uniqueness of definitions within \a component_defs and | |
447 | * reports warnings in case of hiding. */ | |
448 | void chk_uniq(); | |
449 | ||
450 | virtual RunsOnScope *get_scope_runs_on(); | |
451 | virtual Common::Assignment *get_ass_bySRef(Ref_simple *p_ref); | |
452 | virtual bool has_ass_withId(const Identifier& p_id); | |
453 | }; | |
454 | ||
455 | /** | |
456 | * Class Ttcn::Definitions. | |
457 | * | |
458 | * Owns the contained Definition objects. | |
459 | */ | |
460 | class Definitions : public Common::Assignments { | |
461 | protected: | |
462 | /** Searchable map of definitions. Used after chk_uniq. */ | |
463 | map<string, Definition> ass_m; | |
464 | /** Indicates whether the uniqueness of identifiers has been checked. */ | |
465 | bool checked; | |
466 | /** Vector containing all definitions. Used for building. */ | |
467 | vector<Definition> ass_v; | |
468 | ||
469 | Definitions(const Definitions& p); | |
470 | public: | |
471 | ||
472 | Definitions() : Common::Assignments(), ass_m(), checked(false), ass_v() {} | |
473 | ~Definitions(); | |
474 | Definitions *clone() const; | |
475 | virtual void set_fullname(const string& p_fullname); | |
476 | /** Adds the assignment p_ass and becomes the owner of it. | |
477 | * The uniqueness of the identifier is not checked. */ | |
478 | void add_ass(Definition *p_ass); | |
479 | virtual bool has_local_ass_withId(const Identifier& p_id); | |
480 | virtual Common::Assignment* get_local_ass_byId(const Identifier& p_id); | |
481 | virtual size_t get_nof_asss(); | |
482 | virtual Common::Assignment* get_ass_byIndex(size_t p_i); | |
483 | size_t get_nof_raw_asss(); | |
484 | Definition *get_raw_ass_byIndex(size_t p_i); | |
485 | /** Checks the uniqueness of identifiers. */ | |
486 | void chk_uniq(); | |
487 | /** Checks all definitions. */ | |
488 | void chk(); | |
489 | /** Checks the definitions within the header of a for loop. */ | |
490 | void chk_for(); | |
491 | /** Sets the genname of embedded definitions using \a prefix. */ | |
492 | void set_genname(const string& prefix); | |
493 | /** Generates code for all assignments into \a target. */ | |
494 | void generate_code(output_struct *target); | |
495 | void generate_code(CodeGenHelper& cgh); | |
496 | char* generate_code_str(char *str); | |
497 | void ilt_generate_code(ILT *ilt); | |
498 | /** Prints the contents of all assignments. */ | |
499 | virtual void dump(unsigned level) const; | |
500 | }; | |
501 | ||
502 | /** | |
503 | * Class Ttcn::Definitions. | |
504 | * | |
505 | * Owns the contained Definition objects. | |
506 | */ | |
507 | /* class Definitions : public OtherDefinitions { | |
508 | public: | |
509 | Definitions() : OtherDefinitions() {} | |
510 | ~Definitions(); | |
511 | Definitions *clone() const; | |
512 | void add_ass(Definition *p_ass); | |
513 | };*/ | |
514 | ||
515 | /** Represents a TTCN-3 group | |
516 | * | |
517 | * @note a Group is not a Scope */ | |
518 | class Group : public Node, public Location { | |
519 | private: | |
520 | Group* parent_group; | |
521 | WithAttribPath* w_attrib_path; | |
522 | /// Definitions that belong to this group (directly) | |
523 | vector<Definition> ass_v; | |
524 | /// Map the name to the definition (filled in chk_uniq) | |
525 | map<string,Definition> ass_m; | |
526 | /// Subgroups | |
527 | vector<Group> group_v; | |
528 | /// Map the name to the subgroup | |
529 | map<string,Group> group_m; | |
530 | vector<ImpMod> impmods_v; | |
531 | vector<FriendMod> friendmods_v; | |
532 | Identifier *id; | |
533 | bool checked; | |
534 | private: | |
535 | /** Copy constructor not implemented */ | |
536 | Group(const Group& p); | |
537 | /** %Assignment not implemented */ | |
538 | Group& operator=(const Group& p); | |
539 | public: | |
540 | Group(Identifier *p_id); | |
541 | ~Group(); | |
542 | virtual Group* clone() const; | |
543 | virtual void set_fullname(const string& p_fullname); | |
544 | void add_ass(Definition* p_ass); | |
545 | void add_group(Group* p_group); | |
546 | void set_parent_group(Group* p_parent_group); | |
547 | Group* get_parent_group() const { return parent_group; } | |
548 | void set_attrib_path(WithAttribPath* p_path); | |
549 | const Identifier& get_id() const { return *id; } | |
550 | void chk_uniq(); | |
551 | virtual void chk(); | |
552 | void add_impmod(ImpMod *p_impmod); | |
553 | void add_friendmod(FriendMod *p_friendmod); | |
554 | virtual void dump(unsigned level) const; | |
555 | void set_with_attr(MultiWithAttrib* p_attrib); | |
556 | WithAttribPath* get_attrib_path(); | |
557 | void set_parent_path(WithAttribPath* p_path); | |
558 | }; | |
559 | ||
560 | class ControlPart : public Node, public Location { | |
561 | private: | |
562 | StatementBlock* block; | |
563 | WithAttribPath* w_attrib_path; | |
564 | ||
565 | NameBridgingScope bridgeScope; | |
566 | ||
567 | /// Copy constructor disabled | |
568 | ControlPart(const ControlPart& p); | |
569 | /// %Assignment disabled | |
570 | ControlPart& operator=(const ControlPart& p); | |
571 | public: | |
572 | ControlPart(StatementBlock* p_block); | |
573 | ~ControlPart(); | |
574 | virtual ControlPart* clone() const; | |
575 | virtual void set_fullname(const string& p_fullname); | |
576 | virtual void set_my_scope(Scope *p_scope); | |
577 | void chk(); | |
578 | void generate_code(output_struct *target, Module *my_module); | |
579 | void set_with_attr(MultiWithAttrib* p_attrib); | |
580 | WithAttribPath* get_attrib_path(); | |
581 | void set_parent_path(WithAttribPath* p_path); | |
582 | void dump(unsigned level) const; | |
583 | }; | |
584 | ||
585 | /** A TTCN-3 module */ | |
586 | class Module : public Common::Module { | |
587 | private: | |
588 | string *language_spec; | |
589 | Definitions *asss; | |
590 | vector<Group> group_v; | |
591 | map<string, Group> group_m; | |
592 | WithAttribPath* w_attrib_path; | |
593 | Imports *imp; | |
594 | ControlPart* controlpart; | |
595 | /** For caching the scope objects that are created in | |
596 | * \a get_runs_on_scope(). */ | |
597 | vector<RunsOnScope> runs_on_scopes; | |
598 | private: | |
599 | /** Copy constructor not implemented */ | |
600 | Module(const Module& p); | |
601 | /** %Assignment not implemented */ | |
602 | Module& operator=(const Module& p); | |
603 | public: | |
604 | vector<FriendMod> friendmods_v; | |
605 | Module(Identifier *p_modid); | |
606 | ~Module(); | |
607 | void add_group(Group* p_group); | |
608 | void add_friendmod(FriendMod *p_friendmod); | |
609 | virtual Module* clone() const; | |
610 | virtual Common::Assignment* importAssignment( | |
611 | const Identifier& p_source_modid, const Identifier& p_id) const; | |
612 | virtual void set_fullname(const string& p_fullname); | |
613 | virtual Common::Assignments* get_scope_asss(); | |
614 | virtual bool has_imported_ass_withId(const Identifier& p_id); | |
615 | virtual Common::Assignment* get_ass_bySRef(Ref_simple *p_ref); | |
616 | virtual bool is_valid_moduleid(const Identifier& p_id); | |
617 | virtual Common::Assignments *get_asss(); | |
618 | virtual bool exports_sym(const Identifier& p_id); | |
619 | virtual Type *get_address_type(); | |
620 | virtual void chk_imp(ReferenceChain& refch, vector<Common::Module>& moduleStack); | |
621 | virtual void chk(); | |
622 | private: | |
623 | void chk_friends(); | |
624 | void chk_groups(); | |
625 | virtual void get_imported_mods(module_set_t& p_imported_mods); | |
626 | virtual void generate_code_internal(CodeGenHelper& cgh); | |
627 | public: | |
628 | /** Returns a scope that can access the definitions within component type | |
629 | * \a comptype (which is imported from another module) and its parent scope | |
630 | * is \a asss. Note that this scope cannot see the scope of \a comptype. | |
631 | * The function uses \a runs_on_scopes for caching the scope objects: if an | |
632 | * object has been created for a component type it will be returned later | |
633 | * instead of creating a new one. */ | |
634 | RunsOnScope *get_runs_on_scope(Type *comptype); | |
635 | virtual void dump(unsigned level) const; | |
636 | void set_language_spec(const char *p_language_spec); | |
637 | void add_ass(Definition* p_ass); | |
638 | void add_impmod(ImpMod *p_impmod); | |
639 | void add_controlpart(ControlPart* p_controlpart); | |
640 | void set_with_attr(MultiWithAttrib* p_attrib); | |
641 | WithAttribPath* get_attrib_path(); | |
642 | void set_parent_path(WithAttribPath* p_path); | |
643 | const Imports& get_imports() const { return *imp; } | |
644 | ||
645 | bool is_visible(const Identifier& id, visibility_t visibility); | |
646 | ||
af710487 | 647 | /** Generates JSON schema segments for the types defined in the modules, |
648 | * and references to these types. Information related to the types' | |
649 | * JSON encoding and decoding functions is also inserted after the references. | |
650 | * | |
651 | * @param json JSON document containing the main schema, schema segments for | |
652 | * the types will be inserted here | |
653 | * @param json_refs map of JSON documents containing the references and function | |
654 | * info related to each type */ | |
655 | virtual void generate_json_schema(JSON_Tokenizer& json, map<Type*, JSON_Tokenizer>& json_refs); | |
970ed795 EL |
656 | }; |
657 | ||
658 | /** | |
659 | * Module friendship declaration. | |
660 | */ | |
661 | class FriendMod : public Node, public Location { | |
662 | private: | |
663 | Module *my_mod; | |
664 | Identifier *modid; | |
665 | WithAttribPath* w_attrib_path; | |
666 | Group* parentgroup; | |
667 | /** Indicates whether this friend module declaration was checked */ | |
668 | bool checked; | |
669 | private: | |
670 | /** Copy constructor not implemented. */ | |
671 | FriendMod(const FriendMod&); | |
672 | /** %Assignment not implemented. */ | |
673 | FriendMod& operator=(const FriendMod&); | |
674 | public: | |
675 | FriendMod(Identifier *p_modid); | |
676 | ~FriendMod(); | |
677 | virtual FriendMod* clone() const; | |
678 | virtual void set_fullname(const string& p_fullname); | |
679 | virtual void chk(); | |
680 | void set_my_mod(Module *p_mod) { my_mod = p_mod; } | |
681 | const Identifier& get_modid() const {return *modid;} | |
682 | void set_with_attr(MultiWithAttrib* p_attrib); | |
683 | WithAttribPath* get_attrib_path(); | |
684 | void set_parent_path(WithAttribPath* p_path); | |
685 | void set_parent_group(Group* p_group); | |
686 | }; | |
687 | ||
688 | ||
689 | /** | |
690 | * Imported module. Represents an import statement. | |
691 | */ | |
692 | class ImpMod : public Node, public Location { | |
693 | public: | |
694 | enum imptype_t { | |
695 | I_UNDEF, | |
696 | I_ERROR, | |
697 | I_ALL, | |
698 | I_IMPORTSPEC, | |
699 | I_IMPORTIMPORT | |
700 | }; | |
701 | private: | |
702 | /** Points to the target (imported) module. This is initially NULL; | |
703 | * set during semantic analysis by Ttcn::Imports::chk_uniq() */ | |
704 | Common::Module *mod; | |
705 | /** The importing module (indirectly our owner) */ | |
706 | Module *my_mod; | |
707 | /** Import type: "import all", selective import, import of import, etc. */ | |
708 | imptype_t imptype; | |
709 | /** The name given in the import statement; | |
710 | * hopefully an actual module name */ | |
711 | Identifier *modid; | |
712 | /** The text after "import from name language" */ | |
713 | string *language_spec; | |
714 | /** Recursive import (already deprecated in v3.2.1) */ | |
715 | bool is_recursive; | |
716 | WithAttribPath* w_attrib_path; | |
717 | /** Group in which the import statement is located, if any */ | |
718 | Group* parentgroup; | |
719 | visibility_t visibility; | |
720 | private: | |
721 | /** Copy constructor not implemented. */ | |
722 | ImpMod(const ImpMod&); | |
723 | /** %Assignment not implemented */ | |
724 | ImpMod& operator=(const ImpMod&); | |
725 | public: | |
726 | ImpMod(Identifier *p_modid); | |
727 | ~ImpMod(); | |
728 | virtual ImpMod* clone() const; | |
729 | virtual void set_fullname(const string& p_fullname); | |
730 | virtual void chk(); | |
731 | /** Checks the existence of imported symbols and checks import definitions | |
732 | * in the imported modules recursively. */ | |
733 | void chk_imp(ReferenceChain& refch, vector<Common::Module>& moduleStack); | |
734 | void set_my_mod(Module *p_mod) { my_mod = p_mod; } | |
735 | const Identifier& get_modid() const {return *modid;} | |
736 | void set_mod(Common::Module *p_mod) { mod = p_mod; } | |
737 | Common::Module *get_mod() const { return mod; } | |
738 | /** Returns the imported definition with name \a p_id if it is imported or | |
739 | * NULL otherwise. | |
740 | * \a loc is used to report an error if it is needed */ | |
741 | Common::Assignment *get_imported_def(const Identifier& p_source_modid, | |
742 | const Identifier& p_id, const Location *loc, | |
743 | ReferenceChain* refch, vector<ImpMod>& usedImpMods) const; | |
744 | bool has_imported_def(const Identifier& p_source_modid, | |
745 | const Identifier& p_id, const Location *loc) const; | |
746 | void set_imptype(imptype_t p_imptype) { imptype = p_imptype; } | |
747 | void set_language_spec(const char *p_language_spec); | |
748 | void set_recursive() { is_recursive = true; } | |
749 | void generate_code(output_struct *target); | |
750 | virtual void dump(unsigned level) const; | |
751 | void set_with_attr(MultiWithAttrib* p_attrib); | |
752 | WithAttribPath* get_attrib_path(); | |
753 | void set_parent_path(WithAttribPath* p_path); | |
754 | void set_parent_group(Group* p_group); | |
755 | imptype_t get_imptype() { | |
756 | return imptype; | |
757 | } | |
758 | void set_visibility(visibility_t p_visibility){ | |
759 | visibility = p_visibility; | |
760 | } | |
761 | visibility_t get_visibility() const{ | |
762 | return visibility; | |
763 | } | |
764 | }; | |
765 | ||
766 | /** | |
767 | * Class Imports. | |
768 | */ | |
769 | class Imports : public Node { | |
770 | private: | |
771 | /** my module */ | |
772 | Module *my_mod; | |
773 | /** imported modules */ | |
774 | vector<ImpMod> impmods_v; | |
775 | /** Indicates whether the import list has been checked. */ | |
776 | bool checked; | |
777 | ||
778 | friend class ImpMod; | |
779 | private: | |
780 | /** Copy constructor not implemented. */ | |
781 | Imports(const Imports&); | |
782 | /** %Assignment not implemented */ | |
783 | Imports& operator=(const Imports&); | |
784 | public: | |
785 | Imports() : Node(), my_mod(0), impmods_v(), checked(false) {} | |
786 | virtual ~Imports(); | |
787 | virtual Imports* clone() const; | |
788 | void add_impmod(ImpMod *p_impmod); | |
789 | void set_my_mod(Module *p_mod); | |
790 | int get_imports_size() const {return impmods_v.size();} | |
791 | ImpMod* get_impmod(int index) const {return impmods_v[index];} | |
792 | /** Checks the existence of imported modules and detects duplicated imports | |
793 | * from the same module. Initializes \a impmods_m. */ | |
794 | void chk_uniq(); | |
795 | /** Checks the existence of imported symbols and checks import definitions | |
796 | * in the imported modules recursively. */ | |
797 | void chk_imp(ReferenceChain& refch, vector<Common::Module>& moduleStack); | |
798 | /** Returns \p true if an imported module with the given name exists, | |
799 | * else returns \p false. */ | |
800 | bool has_impmod_withId(const Identifier& p_id) const; | |
801 | /** Returns whether a definition with identifier \a p_id is imported | |
802 | * from one or more modules */ | |
803 | bool has_imported_def(const Identifier& p_id, const Location *loc) const; | |
804 | /** Returns the imported definition with name \a p_id if it is | |
805 | * unambiguous or NULL otherwise. | |
806 | * \a loc is used to report an error if it is needed */ | |
807 | Common::Assignment *get_imported_def(const Identifier& p_source_modid, | |
808 | const Identifier& p_id, const Location *loc, ReferenceChain* refch); | |
809 | void get_imported_mods(Module::module_set_t& p_imported_mods) const; | |
810 | void generate_code(output_struct *target); | |
811 | void generate_code(CodeGenHelper& cgh); | |
812 | virtual void dump(unsigned level) const; | |
813 | }; | |
814 | ||
815 | class Definition : public Common::Assignment { | |
816 | protected: // many derived classes | |
817 | /** Contains the C++ identifier of the definition. If empty the C++ | |
818 | * identifier is generated from \a id. */ | |
819 | string genname; | |
820 | /** The group it's in, if any */ | |
821 | Group *parentgroup; | |
822 | WithAttribPath* w_attrib_path; | |
823 | ErroneousAttributes* erroneous_attrs; // set by chk_erroneous_attr() or NULL | |
824 | /** True if function/altstep/default scope, not module scope */ | |
825 | bool local_scope; | |
826 | ||
827 | Definition(const Definition& p) | |
828 | : Common::Assignment(p), genname(), parentgroup(0), | |
829 | w_attrib_path(0), erroneous_attrs(0), local_scope(false) | |
830 | { } | |
831 | virtual string get_genname() const; | |
832 | ||
833 | namedbool has_implicit_omit_attr() const; | |
834 | private: | |
835 | /// %Assignment disabled | |
836 | Definition& operator=(const Definition& p); | |
837 | public: | |
838 | Definition(asstype_t p_asstype, Identifier *p_id) | |
839 | : Common::Assignment(p_asstype, p_id), genname(), parentgroup(0), | |
840 | w_attrib_path(0), erroneous_attrs(0), local_scope(false) | |
841 | { } | |
842 | virtual ~Definition(); | |
843 | virtual Definition* clone() const = 0; | |
844 | virtual void set_fullname(const string& p_fullname); | |
845 | virtual bool is_local() const; | |
846 | /** Sets the visibility type of the definition */ | |
847 | void set_visibility(const visibility_t p_visibility) | |
848 | { visibilitytype = p_visibility; } | |
849 | /** Marks the (template) definition as local to a func/altstep/default */ | |
850 | inline void set_local() { local_scope = true; } | |
851 | ||
852 | void set_genname(const string& p_genname) { genname = p_genname; } | |
853 | /** Check if two definitions are (almost) identical, the type and dimensions | |
854 | * must always be identical, the initial values can be different depending | |
855 | * on the definition type. If error was reported the return value is false. | |
856 | * The initial values (if applicable) may be present/absent, different or | |
857 | * unfoldable. The function must be overridden to be used. | |
858 | */ | |
859 | virtual bool chk_identical(Definition *p_def); | |
860 | /** Parse and check the erroneous attribute data, | |
861 | * sets erroneous_attrs member */ | |
862 | void chk_erroneous_attr(); | |
863 | /** This code generation is used when this definition is embedded | |
864 | * in a statement block. */ | |
865 | virtual char* generate_code_str(char *str); | |
866 | virtual void ilt_generate_code(ILT *ilt); | |
867 | /** Generates the C++ initializer sequence for a definition of a component | |
868 | * type, appends to \a str and returns the resulting string. The function | |
869 | * is used when \a this is realized using the C++ objects of definition | |
870 | * \a base_defn inherited from another component type. The function is | |
871 | * implemented only for those definitions that can appear within component | |
872 | * types, the generic version causes \a FATAL_ERROR. */ | |
873 | virtual char *generate_code_init_comp(char *str, Definition *base_defn); | |
874 | virtual void dump_internal(unsigned level) const; | |
875 | virtual void dump(unsigned level) const; | |
876 | virtual void set_with_attr(MultiWithAttrib* p_attrib); | |
877 | virtual WithAttribPath* get_attrib_path(); | |
878 | virtual void set_parent_path(WithAttribPath* p_path); | |
879 | virtual void set_parent_group(Group* p_group); | |
880 | virtual Group* get_parent_group(); | |
881 | }; | |
882 | ||
883 | /** | |
884 | * TTCN-3 type definition (including signatures and port types). | |
885 | */ | |
886 | class Def_Type : public Definition { | |
887 | private: | |
888 | Type *type; | |
889 | ||
890 | NameBridgingScope bridgeScope; | |
891 | ||
892 | /** Copy constructor not implemented */ | |
893 | Def_Type(const Def_Type& p); | |
894 | /** %Assignment disabled */ | |
895 | Def_Type& operator=(const Def_Type& p); | |
896 | public: | |
897 | Def_Type(Identifier *p_id, Type *p_type); | |
898 | virtual ~Def_Type(); | |
899 | virtual Def_Type* clone() const; | |
900 | virtual void set_fullname(const string& p_fullname); | |
901 | virtual void set_my_scope(Scope *p_scope); | |
902 | virtual Setting *get_Setting(); | |
903 | virtual Type *get_Type(); | |
904 | virtual void chk(); | |
905 | virtual void generate_code(output_struct *target, bool clean_up = false); | |
906 | virtual void generate_code(CodeGenHelper& cgh); | |
907 | virtual void dump_internal(unsigned level) const; | |
908 | virtual void set_with_attr(MultiWithAttrib* p_attrib); | |
909 | virtual WithAttribPath* get_attrib_path(); | |
910 | virtual void set_parent_path(WithAttribPath* p_path); | |
970ed795 EL |
911 | }; |
912 | ||
913 | /** | |
914 | * TTCN-3 constant definition. | |
915 | */ | |
916 | class Def_Const : public Definition { | |
917 | private: | |
918 | Type *type; | |
919 | Value *value; | |
920 | bool value_under_check; | |
921 | ||
922 | /// Copy constructor disabled | |
923 | Def_Const(const Def_Const& p); | |
924 | /// %Assignment disabled | |
925 | Def_Const& operator=(const Def_Const& p); | |
926 | public: | |
927 | Def_Const(Identifier *p_id, Type *p_type, Value *p_value); | |
928 | virtual ~Def_Const(); | |
929 | virtual Def_Const *clone() const; | |
930 | virtual void set_fullname(const string& p_fullname); | |
931 | virtual void set_my_scope(Scope *p_scope); | |
932 | virtual Setting *get_Setting(); | |
933 | virtual Type *get_Type(); | |
934 | virtual Value *get_Value(); | |
935 | virtual void chk(); | |
936 | virtual bool chk_identical(Definition *p_def); | |
937 | virtual void generate_code(output_struct *target, bool clean_up = false); | |
938 | virtual void generate_code(CodeGenHelper& cgh); | |
939 | virtual char* generate_code_str(char *str); | |
940 | virtual void ilt_generate_code(ILT *ilt); | |
941 | virtual char *generate_code_init_comp(char *str, Definition *base_defn); | |
942 | virtual void dump_internal(unsigned level) const; | |
943 | }; | |
944 | ||
945 | /** | |
946 | * TTCN-3 external constant definition. | |
947 | */ | |
948 | class Def_ExtConst : public Definition { | |
949 | private: | |
950 | Type *type; | |
951 | ||
952 | /// Copy constructor disabled | |
953 | Def_ExtConst(const Def_ExtConst& p); | |
954 | /// %Assignment disabled | |
955 | Def_ExtConst& operator=(const Def_ExtConst& p); | |
956 | public: | |
957 | Def_ExtConst(Identifier *p_id, Type *p_type); | |
958 | virtual ~Def_ExtConst(); | |
959 | virtual Def_ExtConst *clone() const; | |
960 | virtual void set_fullname(const string& p_fullname); | |
961 | virtual void set_my_scope(Scope *p_scope); | |
962 | virtual Type *get_Type(); | |
963 | virtual void chk(); | |
964 | virtual void generate_code(output_struct *target, bool clean_up = false); | |
965 | virtual void generate_code(CodeGenHelper& cgh); | |
966 | virtual void dump_internal(unsigned level) const; | |
967 | }; | |
968 | ||
969 | /** | |
970 | * TTCN-3 module parameter definition. | |
971 | */ | |
972 | class Def_Modulepar : public Definition { | |
973 | private: | |
974 | Type *type; | |
975 | Value* def_value; | |
976 | /// Copy constructor disabled | |
977 | Def_Modulepar(const Def_Modulepar& p); | |
978 | /// %Assignment disabled | |
979 | Def_Modulepar& operator=(const Def_Modulepar& p); | |
980 | public: | |
981 | Def_Modulepar(Identifier *p_id, Type *p_type, Value *p_defval); | |
982 | virtual ~Def_Modulepar(); | |
983 | virtual Def_Modulepar* clone() const; | |
984 | virtual void set_fullname(const string& p_fullname); | |
985 | virtual void set_my_scope(Scope *p_scope); | |
986 | virtual Type *get_Type(); | |
987 | virtual void chk(); | |
988 | virtual void generate_code(output_struct *target, bool clean_up = false); | |
989 | virtual void generate_code(CodeGenHelper& cgh); | |
990 | virtual void dump_internal(unsigned level) const; | |
991 | }; | |
992 | ||
993 | /** | |
994 | * TTCN-3 template module parameter definition. | |
995 | */ | |
996 | class Def_Modulepar_Template : public Definition { | |
997 | private: | |
998 | Type *type; | |
999 | Template* def_template; | |
1000 | /// Copy constructor disabled | |
1001 | Def_Modulepar_Template(const Def_Modulepar_Template& p); | |
1002 | /// %Assignment disabled | |
1003 | Def_Modulepar_Template& operator=(const Def_Modulepar_Template& p); | |
1004 | public: | |
1005 | Def_Modulepar_Template(Identifier *p_id, Type *p_type, Template *p_defval); | |
1006 | virtual ~Def_Modulepar_Template(); | |
1007 | virtual Def_Modulepar_Template* clone() const; | |
1008 | virtual void set_fullname(const string& p_fullname); | |
1009 | virtual void set_my_scope(Scope *p_scope); | |
1010 | virtual Type *get_Type(); | |
1011 | virtual void chk(); | |
1012 | virtual void generate_code(output_struct *target, bool clean_up = false); | |
1013 | virtual void generate_code(CodeGenHelper& cgh); | |
1014 | virtual void dump_internal(unsigned level) const; | |
1015 | }; | |
1016 | ||
1017 | /** | |
1018 | * Def_Template class represents a template definition. | |
1019 | */ | |
1020 | class Def_Template : public Definition { | |
1021 | private: | |
1022 | /* the type of the template */ | |
1023 | Type *type; | |
1024 | /** The formal parameter list of the template. It is NULL in case of | |
1025 | * non-parameterized templates. */ | |
1026 | FormalParList *fp_list; | |
1027 | /** points to the base template reference in case of modified templates, | |
1028 | * otherwise it is NULL */ | |
1029 | Reference *derived_ref; | |
1030 | /** shortcut to the base template in case of modified templates, | |
1031 | * otherwise it is NULL */ | |
1032 | Def_Template *base_template; | |
1033 | /** Indicates whether the circular recursion chain of modified templates | |
1034 | * has been checked. */ | |
1035 | bool recurs_deriv_checked; | |
1036 | /** the body of the template */ | |
1037 | Template *body; | |
1038 | /** template definition level restriction */ | |
1039 | template_restriction_t template_restriction; | |
1040 | /** set in chk(), used by code generation, | |
1041 | * valid if template_restriction!=TR_NONE */ | |
1042 | bool gen_restriction_check; | |
1043 | ||
1044 | NameBridgingScope bridgeScope; | |
1045 | ||
1046 | /// Copy constructor for Def_Template::clone() only | |
1047 | Def_Template(const Def_Template& p); | |
1048 | /// %Assignment disabled | |
1049 | Def_Template& operator=(const Def_Template& p); | |
1050 | public: | |
1051 | Def_Template(template_restriction_t p_template_restriction, | |
1052 | Identifier *p_id, Type *p_type, FormalParList *p_fpl, | |
1053 | Reference *p_derived_ref, Template *p_body); | |
1054 | virtual ~Def_Template(); | |
1055 | virtual Def_Template *clone() const; | |
1056 | virtual void set_fullname(const string& p_fullname); | |
1057 | virtual void set_my_scope(Scope *p_scope); | |
1058 | virtual Setting *get_Setting(); | |
1059 | virtual Type *get_Type(); | |
1060 | virtual Template *get_Template(); | |
1061 | virtual FormalParList *get_FormalParList(); | |
1062 | virtual void chk(); | |
1063 | private: | |
1064 | void chk_modified(); | |
1065 | void chk_default() const; | |
1066 | void chk_recursive_derivation(); | |
1067 | public: | |
1068 | virtual void generate_code(output_struct *target, bool clean_up = false); | |
1069 | virtual void generate_code(CodeGenHelper& cgh); | |
1070 | virtual char* generate_code_str(char *str); | |
1071 | virtual void ilt_generate_code(ILT *ilt); | |
1072 | virtual void dump_internal(unsigned level) const; | |
1073 | template_restriction_t get_template_restriction() | |
1074 | { return template_restriction; } | |
1075 | }; | |
1076 | ||
1077 | /** | |
1078 | * Def_Var class represents a variable definition. | |
1079 | */ | |
1080 | class Def_Var : public Definition { | |
1081 | private: | |
1082 | Type *type; | |
1083 | /** the initial value: optional and maybe incomplete */ | |
1084 | Value *initial_value; | |
1085 | ||
1086 | /// Copy constructor disabled | |
1087 | Def_Var(const Def_Var& p); | |
1088 | /// %Assignment disabled | |
1089 | Def_Var& operator=(const Def_Var& p); | |
1090 | public: | |
1091 | Def_Var(Identifier *p_id, Type *p_type, Value *p_initial_value); | |
1092 | virtual ~Def_Var(); | |
1093 | virtual Def_Var *clone() const; | |
1094 | virtual void set_fullname(const string& p_fullname); | |
1095 | virtual void set_my_scope(Scope *p_scope); | |
1096 | virtual Type *get_Type(); | |
1097 | virtual void chk(); | |
1098 | virtual bool chk_identical(Definition *p_def); | |
1099 | virtual void generate_code(output_struct *target, bool clean_up = false); | |
1100 | virtual void generate_code(CodeGenHelper& cgh); | |
1101 | virtual char* generate_code_str(char *str); | |
1102 | virtual void ilt_generate_code(ILT *ilt); | |
1103 | virtual char *generate_code_init_comp(char *str, Definition *base_defn); | |
1104 | virtual void dump_internal(unsigned level) const; | |
1105 | }; | |
1106 | ||
1107 | /** | |
1108 | * Def_Var_Template class represents a template variable (dynamic template) | |
1109 | * definition. | |
1110 | */ | |
1111 | class Def_Var_Template : public Definition { | |
1112 | private: | |
1113 | Type *type; | |
1114 | /** the initial value: optional and maybe incomplete */ | |
1115 | Template *initial_value; | |
1116 | /** optional restriction on this variable */ | |
1117 | template_restriction_t template_restriction; | |
1118 | /** set in chk(), used by code generation, | |
1119 | * valid if template_restriction!=TR_NONE */ | |
1120 | bool gen_restriction_check; | |
1121 | ||
1122 | /// Copy constructor disabled | |
1123 | Def_Var_Template(const Def_Var_Template& p); | |
1124 | /// %Assignment disabled | |
1125 | Def_Var_Template& operator=(const Def_Var_Template& p); | |
1126 | public: | |
1127 | Def_Var_Template(Identifier *p_id, Type *p_type, Template *p_initial_value, | |
1128 | template_restriction_t p_template_restriction); | |
1129 | virtual ~Def_Var_Template(); | |
1130 | virtual Def_Var_Template *clone() const; | |
1131 | virtual void set_fullname(const string& p_fullname); | |
1132 | virtual void set_my_scope(Scope *p_scope); | |
1133 | virtual Type *get_Type(); | |
1134 | virtual void chk(); | |
1135 | virtual bool chk_identical(Definition *p_def); | |
1136 | virtual void generate_code(output_struct *target, bool clean_up = false); | |
1137 | virtual void generate_code(CodeGenHelper& cgh); | |
1138 | virtual char* generate_code_str(char *str); | |
1139 | virtual void ilt_generate_code(ILT *ilt); | |
1140 | virtual char *generate_code_init_comp(char *str, Definition *base_defn); | |
1141 | virtual void dump_internal(unsigned level) const; | |
1142 | template_restriction_t get_template_restriction() | |
1143 | { return template_restriction; } | |
1144 | }; | |
1145 | ||
1146 | /** | |
1147 | * Def_Timer class represents a single timer declaration (e.g. in a | |
1148 | * TTCN component type). | |
1149 | */ | |
1150 | class Def_Timer : public Definition { | |
1151 | private: | |
1152 | /** Describes the dimensions of a timer array. It is NULL in case | |
1153 | * of single timer instance. */ | |
1154 | ArrayDimensions *dimensions; | |
1155 | /** Default duration of the timers. It can be either a single | |
1156 | * float value or an array of floats. If it is NULL the timer(s) | |
1157 | * has no default duration. */ | |
1158 | Value *default_duration; | |
1159 | ||
1160 | /// Copy constructor disabled | |
1161 | Def_Timer(const Def_Timer& p); | |
1162 | /// %Assignment disabled | |
1163 | Def_Timer& operator=(const Def_Timer& p); | |
1164 | public: | |
1165 | Def_Timer(Identifier *p_id, ArrayDimensions *p_dims, Value *p_dur) | |
1166 | : Definition(A_TIMER, p_id), dimensions(p_dims), | |
1167 | default_duration(p_dur) { } | |
1168 | virtual ~Def_Timer(); | |
1169 | virtual Def_Timer *clone() const; | |
1170 | virtual void set_fullname(const string& p_fullname); | |
1171 | virtual void set_my_scope(Scope *p_scope); | |
1172 | virtual ArrayDimensions *get_Dimensions(); | |
1173 | virtual void chk(); | |
1174 | virtual bool chk_identical(Definition *p_def); | |
1175 | /** Returns false if it is sure that the timer referred by array | |
1176 | * indices \a p_subrefs does not have a default | |
1177 | * duration. Otherwise it returns true. Argument \a p_subrefs | |
1178 | * might be NULL when examining a single timer. */ | |
1179 | bool has_default_duration(FieldOrArrayRefs *p_subrefs); | |
1180 | private: | |
1181 | /** Checks if the value \a dur is suitable as duration for a single | |
1182 | * timer. */ | |
1183 | void chk_single_duration(Value *dur); | |
1184 | /** Checks if the value \a dur is suitable as duration for a timer | |
1185 | * array. The function calls itself recursively, argument \a | |
1186 | * start_dim shall be zero when called from outside. */ | |
1187 | void chk_array_duration(Value *dur, size_t start_dim = 0); | |
1188 | public: | |
1189 | virtual void generate_code(output_struct *target, bool clean_up = false); | |
1190 | virtual void generate_code(CodeGenHelper& cgh); | |
1191 | private: | |
1192 | /** Generates a C++ code fragment that sets the default duration | |
1193 | * of a timer array. The generated code is appended to \a str and | |
1194 | * the resulting string is returned. The equivalent C++ object of | |
1195 | * timer array is named \a object_name, the array value containing | |
1196 | * the default durations is \a dur. The function calls itself | |
1197 | * recursively, argument \a start_dim shall be zero when called | |
1198 | * from outside. */ | |
1199 | char *generate_code_array_duration(char *str, const char *object_name, | |
1200 | Value *dur, size_t start_dim = 0); | |
1201 | public: | |
1202 | virtual char* generate_code_str(char *str); | |
1203 | virtual void ilt_generate_code(ILT *ilt); | |
1204 | virtual char *generate_code_init_comp(char *str, Definition *base_defn); | |
1205 | virtual void dump_internal(unsigned level) const; | |
1206 | }; | |
1207 | ||
1208 | /** | |
1209 | * Def_Port class represents a port declaration (in a component type). | |
1210 | */ | |
1211 | class Def_Port : public Definition { | |
1212 | private: | |
1213 | /** Contains a reference to a TTCN-3 port type */ | |
1214 | Reference *type_ref; | |
1215 | /** Points to the object describing the port type. | |
1216 | * | |
1217 | * Derived from \a type_ref during Def_Port::chk(). | |
1218 | * It can be NULL in case of any error (e.g. the reference points to a | |
1219 | * non-existent port type or the referenced entity is not a port type. */ | |
1220 | Type *port_type; | |
1221 | /** Describes the dimensions of a port array. | |
1222 | * It is NULL in case of single port instance. */ | |
1223 | ArrayDimensions *dimensions; | |
1224 | ||
1225 | /// Copy constructor disabled | |
1226 | Def_Port(const Def_Port& p); | |
1227 | /// %Assignment disabled | |
1228 | Def_Port& operator=(const Def_Port& p); | |
1229 | public: | |
1230 | /** Constructor | |
1231 | * | |
1232 | * @param p_id identifier (must not be NULL), the name of the port | |
1233 | * @param p_tref type reference (must not be NULL) | |
1234 | * @param p_dims array dimensions (NULL for a single port instance) | |
1235 | */ | |
1236 | Def_Port(Identifier *p_id, Reference *p_tref, ArrayDimensions *p_dims); | |
1237 | virtual ~Def_Port(); | |
1238 | virtual Def_Port *clone() const; | |
1239 | virtual void set_fullname(const string& p_fullname); | |
1240 | virtual void set_my_scope(Scope *p_scope); | |
1241 | /** Get the \a port_type | |
1242 | * | |
1243 | * @pre chk() has been called (because it computes \a port_type) | |
1244 | */ | |
1245 | virtual Type *get_Type(); | |
1246 | virtual ArrayDimensions *get_Dimensions(); | |
1247 | virtual void chk(); | |
1248 | virtual bool chk_identical(Definition *p_def); | |
1249 | virtual void generate_code(output_struct *target, bool clean_up = false); | |
1250 | virtual void generate_code(CodeGenHelper& cgh); | |
1251 | virtual char *generate_code_init_comp(char *str, Definition *base_defn); | |
1252 | virtual void dump_internal(unsigned level) const; | |
1253 | }; | |
1254 | ||
1255 | /** | |
1256 | * Common base class for function and external function definitions. | |
1257 | */ | |
1258 | class Def_Function_Base : public Definition { | |
1259 | public: | |
1260 | enum prototype_t { | |
1261 | PROTOTYPE_NONE, /**< no prototype(...) attribute */ | |
1262 | PROTOTYPE_CONVERT, /**< attribute prototype(convert) */ | |
1263 | PROTOTYPE_FAST, /**< attribute prototype(fast) */ | |
1264 | PROTOTYPE_BACKTRACK, /**< attribute prototype(backtrack) */ | |
1265 | PROTOTYPE_SLIDING /**< attribute prototype(sliding) */ | |
1266 | }; | |
1267 | protected: // Def_Function and Def_ExtFunction need access | |
1268 | /** The formal parameter list of the function. It is never NULL even if | |
1269 | * the function has empty parameter list. Owned. */ | |
1270 | FormalParList *fp_list; | |
1271 | /** The return type of the function or NULL in case of no return type. | |
1272 | * Owned. */ | |
1273 | Type *return_type; | |
1274 | /** Identifier of the enc/dec API implemented by the function */ | |
1275 | prototype_t prototype; | |
1276 | /** Shortcut to the input type if the function implements one of the | |
1277 | * enc/dec APIs or NULL otherwise. Not owned. */ | |
1278 | Type *input_type; | |
1279 | /** Shortcut to the output type if the function implements one of the | |
1280 | * enc/dec APIs or NULL otherwise. Not owned */ | |
1281 | Type *output_type; | |
1282 | /** optional template restriction on return template value */ | |
1283 | template_restriction_t template_restriction; | |
1284 | ||
1285 | static asstype_t determine_asstype(bool is_external, bool has_return_type, | |
1286 | bool returns_template); | |
1287 | /// Copy constructor disabled | |
1288 | Def_Function_Base(const Def_Function_Base& p); | |
1289 | /// %Assignment disabled | |
1290 | Def_Function_Base& operator=(const Def_Function_Base& p); | |
1291 | public: | |
1292 | /** Constructor. | |
1293 | * | |
1294 | * @param is_external true if external function (the derived type is | |
1295 | * Def_ExtFunction), false if a TTCN-3 function (Def_Function) | |
1296 | * @param p_id the name of the function | |
1297 | * @param p_fpl formal parameter list | |
1298 | * @param p_return_type return type (may be NULL) | |
1299 | * @param returns_template true if the return is a template | |
1300 | * @param p_template_restriction restriction type | |
1301 | */ | |
1302 | Def_Function_Base(bool is_external, Identifier *p_id, | |
1303 | FormalParList *p_fpl, Type *p_return_type, bool returns_template, | |
1304 | template_restriction_t p_template_restriction); | |
1305 | virtual ~Def_Function_Base(); | |
1306 | virtual void set_fullname(const string& p_fullname); | |
1307 | virtual void set_my_scope(Scope *p_scope); | |
1308 | virtual Type *get_Type(); | |
1309 | virtual FormalParList *get_FormalParList(); | |
1310 | prototype_t get_prototype() const { return prototype; } | |
1311 | void set_prototype(prototype_t p_prototype) { prototype = p_prototype; } | |
1312 | const char *get_prototype_name() const; | |
1313 | void chk_prototype(); | |
1314 | Type *get_input_type(); | |
1315 | Type *get_output_type(); | |
1316 | template_restriction_t get_template_restriction() | |
1317 | { return template_restriction; } | |
1318 | }; | |
1319 | ||
1320 | /** | |
1321 | * Def_Function class represents a function definition. | |
1322 | */ | |
1323 | class Def_Function : public Def_Function_Base { | |
1324 | private: | |
1325 | /** The 'runs on' clause (i.e. a reference to a TTCN-3 component type) | |
1326 | * It is NULL if the function has no 'runs on' clause. */ | |
1327 | Reference *runs_on_ref; | |
1328 | /** Points to the object describing the component type referred by | |
1329 | * 'runs on' clause. | |
1330 | * It is NULL if the function has no 'runs on' clause or \a runs_on_ref is | |
1331 | * erroneous. */ | |
1332 | Type *runs_on_type; | |
1333 | /** The body of the function */ | |
1334 | StatementBlock *block; | |
1335 | /** Indicates whether the function is startable. That is, it can be | |
1336 | * launched as PTC behaviour as argument of a start test component | |
1337 | * statement. */ | |
1338 | bool is_startable; | |
1339 | /** Opts out from location information */ | |
1340 | bool transparent; | |
1341 | ||
1342 | NameBridgingScope bridgeScope; | |
1343 | ||
1344 | /// Copy constructor disabled | |
1345 | Def_Function(const Def_Function& p); | |
1346 | /// %Assignment disabled | |
1347 | Def_Function& operator=(const Def_Function& p); | |
1348 | public: | |
1349 | /** Constructor for a TTCN-3 function definition | |
1350 | * | |
1351 | * Called from a single location in compiler.y | |
1352 | * | |
1353 | * @param p_id function name | |
1354 | * @param p_fpl formal parameter list | |
1355 | * @param p_runs_on_ref "runs on", else NULL | |
1356 | * @param p_return_type return type, may be NULL | |
1357 | * @param returns_template true if the return value is a template | |
1358 | * @param p_template_restriction restriction type | |
1359 | * @param p_block the body of the function | |
1360 | */ | |
1361 | Def_Function(Identifier *p_id, FormalParList *p_fpl, | |
1362 | Reference *p_runs_on_ref, Type *p_return_type, | |
1363 | bool returns_template, | |
1364 | template_restriction_t p_template_restriction, | |
1365 | StatementBlock *p_block); | |
1366 | virtual ~Def_Function(); | |
1367 | virtual Def_Function *clone() const; | |
1368 | virtual void set_fullname(const string& p_fullname); | |
1369 | virtual void set_my_scope(Scope *p_scope); | |
1370 | virtual Type *get_RunsOnType(); | |
1371 | /** Returns a scope that can access the definitions within component type | |
1372 | * \a comptype and its parent is \a parent_scope.*/ | |
1373 | RunsOnScope *get_runs_on_scope(Type *comptype); | |
1374 | virtual void chk(); | |
1375 | /** Checks and returns whether the function is startable. | |
1376 | * Reports the appropriate error message(s) if not. */ | |
1377 | bool chk_startable(); | |
1378 | ||
1379 | bool is_transparent() const { return transparent; } | |
1380 | ||
1381 | virtual void generate_code(output_struct *target, bool clean_up = false); | |
1382 | virtual void generate_code(CodeGenHelper& cgh); | |
1383 | virtual void dump_internal(unsigned level) const; | |
1384 | ||
1385 | virtual void set_parent_path(WithAttribPath* p_path); | |
1386 | }; | |
1387 | ||
1388 | /** RAII class for transparent functions. | |
1389 | * | |
1390 | * Calls to TTCN_Location::update_lineno are written by Ttcn::Statement | |
1391 | * by calling Common::Location::update_location_object. These calls | |
1392 | * need to be removed inside transparent functions. | |
1393 | * | |
1394 | * It is difficult (impossible) for a Statement to navigate up in the AST | |
1395 | * to the function/altstep/testcase/control part that contains it; | |
1396 | * instead, the Def_Function sets a static flag inside Common::Location | |
1397 | * that says "you are inside a transparent function" while | |
1398 | * Def_Function::generate_code function runs. | |
1399 | */ | |
1400 | class transparency_holder { | |
1401 | bool old_transparency; | |
1402 | public: | |
1403 | /** Sets Common::Location::transparency (but remembers its old vaue) | |
1404 | * | |
1405 | * @param df the function definition | |
1406 | */ | |
1407 | transparency_holder(const Def_Function &df) | |
1408 | : old_transparency(Common::Location::transparency) | |
1409 | { Common::Location::transparency = df.is_transparent(); } | |
1410 | ||
1411 | /** Restores the value of Common::Location::transparency */ | |
1412 | ~transparency_holder() | |
1413 | { Common::Location::transparency = old_transparency; } | |
1414 | }; | |
1415 | ||
1416 | /** | |
1417 | * Def_ExtFunction class represents an external function definition. | |
1418 | */ | |
1419 | class Def_ExtFunction : public Def_Function_Base { | |
1420 | public: | |
1421 | enum ExternalFunctionType_t { | |
1422 | EXTFUNC_MANUAL, /**< written manually by the user */ | |
1423 | EXTFUNC_ENCODE, /**< automatically generated encoder function */ | |
1424 | EXTFUNC_DECODE /**< automatically generated decoder function */ | |
1425 | }; | |
1426 | private: | |
1427 | ExternalFunctionType_t function_type; | |
1428 | Type::MessageEncodingType_t encoding_type; | |
1429 | string *encoding_options; | |
1430 | Ttcn::ErrorBehaviorList *eb_list; | |
1431 | Ttcn::PrintingType *json_printing; | |
1432 | /// Copy constructor disabled | |
1433 | Def_ExtFunction(const Def_ExtFunction& p); | |
1434 | /// %Assignment disabled | |
1435 | Def_ExtFunction& operator=(const Def_ExtFunction& p); | |
1436 | public: | |
1437 | /** Constructor for an external function definition | |
1438 | * | |
1439 | * Called from a single location in compiler.y | |
1440 | * | |
1441 | * @param p_id the name | |
1442 | * @param p_fpl formal parameters | |
1443 | * @param p_return_type the return type | |
1444 | * @param returns_template true if it returns a template | |
1445 | * @param p_template_restriction restriction type | |
1446 | */ | |
1447 | Def_ExtFunction(Identifier *p_id, FormalParList *p_fpl, | |
1448 | Type *p_return_type, bool returns_template, | |
1449 | template_restriction_t p_template_restriction) | |
1450 | : Def_Function_Base(true, p_id, p_fpl, p_return_type, returns_template, | |
1451 | p_template_restriction), | |
1452 | function_type(EXTFUNC_MANUAL), encoding_type(Type::CT_UNDEF), | |
1453 | encoding_options(0), eb_list(0), json_printing(0) { } | |
1454 | ~Def_ExtFunction(); | |
1455 | virtual Def_ExtFunction *clone() const; | |
1456 | virtual void set_fullname(const string& p_fullname); | |
1457 | void set_encode_parameters(Type::MessageEncodingType_t p_encoding_type, | |
1458 | string *p_encoding_options); | |
1459 | void set_decode_parameters(Type::MessageEncodingType_t p_encoding_type, | |
1460 | string *p_encoding_options); | |
1461 | void add_eb_list(Ttcn::ErrorBehaviorList *p_eb_list); | |
1462 | ExternalFunctionType_t get_function_type() const { return function_type; } | |
1463 | private: | |
1464 | void chk_function_type(); | |
1465 | void chk_allowed_encode(); | |
1466 | public: | |
1467 | virtual void chk(); | |
1468 | private: | |
1469 | char *generate_code_encode(char *str); | |
1470 | char *generate_code_decode(char *str); | |
1471 | public: | |
1472 | virtual void generate_code(output_struct *target, bool clean_up = false); | |
1473 | /// Just a shim for code splitting | |
1474 | virtual void generate_code(CodeGenHelper& cgh); | |
1475 | virtual void dump_internal(unsigned level) const; | |
1476 | ||
1477 | /** For JSON encoding and decoding functions only | |
1478 | * Generates a JSON schema segment containing a reference to the encoded | |
1479 | * type's schema and any information required to recreate this function. | |
1480 | * If the schema with the reference already exists, the function's info is | |
1481 | * inserted in the schema. */ | |
1482 | void generate_json_schema_ref(map<Type*, JSON_Tokenizer>& json_refs); | |
1483 | }; | |
1484 | ||
1485 | /** | |
1486 | * Represents an altstep definition. | |
1487 | */ | |
1488 | class Def_Altstep : public Definition { | |
1489 | private: | |
1490 | /** The formal parameter list of the altstep. It is never NULL even if | |
1491 | * the altstep has no parameters. */ | |
1492 | FormalParList *fp_list; | |
1493 | /** The 'runs on' clause (i.e. a reference to a TTCN-3 component type) | |
1494 | * It is NULL if the altstep has no 'runs on' clause. */ | |
1495 | Reference *runs_on_ref; | |
1496 | /** Points to the object describing the component type referred by | |
1497 | * 'runs on' clause. | |
1498 | * It is NULL if the altstep has no 'runs on' clause or \a runs_on_ref is | |
1499 | * erroneous. */ | |
1500 | Type *runs_on_type; | |
1501 | StatementBlock *sb; /**< contains the local definitions */ | |
1502 | AltGuards *ags; | |
1503 | ||
1504 | NameBridgingScope bridgeScope; | |
1505 | ||
1506 | /// Copy constructor disabled | |
1507 | Def_Altstep(const Def_Altstep& p); | |
1508 | /// %Assignment disabled | |
1509 | Def_Altstep& operator=(const Def_Altstep& p); | |
1510 | public: | |
1511 | Def_Altstep(Identifier *p_id, FormalParList *p_fpl, | |
1512 | Reference *p_runs_on_ref, StatementBlock *p_sb, | |
1513 | AltGuards *p_ags); | |
1514 | virtual ~Def_Altstep(); | |
1515 | virtual Def_Altstep *clone() const; | |
1516 | virtual void set_fullname(const string& p_fullname); | |
1517 | virtual void set_my_scope(Scope *p_scope); | |
1518 | virtual Type *get_RunsOnType(); | |
1519 | virtual FormalParList *get_FormalParList(); | |
1520 | /** Returns a scope that can access the definitions within component type | |
1521 | * \a comptype and its parent is \a parent_scope.*/ | |
1522 | RunsOnScope *get_runs_on_scope(Type *comptype); | |
1523 | virtual void chk(); | |
1524 | virtual void generate_code(output_struct *target, bool clean_up = false); | |
1525 | virtual void generate_code(CodeGenHelper& cgh); | |
1526 | virtual void dump_internal(unsigned level) const; | |
1527 | ||
1528 | virtual void set_parent_path(WithAttribPath* p_path); | |
1529 | }; | |
1530 | ||
1531 | /** | |
1532 | * Represents an testcase definition. | |
1533 | */ | |
1534 | class Def_Testcase : public Definition { | |
1535 | private: | |
1536 | /** The formal parameter list of the testcase. It is never NULL even if | |
1537 | * the testcase has no parameters. */ | |
1538 | FormalParList *fp_list; | |
1539 | /** The 'runs on' clause (i.e. a reference to a TTCN-3 component type) | |
1540 | * It is never NULL. */ | |
1541 | Reference *runs_on_ref; | |
1542 | /** Points to the object describing the component type referred by | |
1543 | * 'runs on' clause. It is NULL only if \a runs_on_ref is erroneous. */ | |
1544 | Type *runs_on_type; | |
1545 | /** The 'system' clause (i.e. a reference to a TTCN-3 component type) | |
1546 | * It is NULL if the testcase has no 'system' clause. */ | |
1547 | Reference *system_ref; | |
1548 | /** Points to the object describing the component type referred by | |
1549 | * 'system' clause. It is NULL if the testcase has no 'system' clause or | |
1550 | * \a system_ref is erroneous. */ | |
1551 | Type *system_type; | |
1552 | StatementBlock *block; | |
1553 | ||
1554 | NameBridgingScope bridgeScope; | |
1555 | ||
1556 | /// Copy constructor disabled | |
1557 | Def_Testcase(const Def_Testcase& p); | |
1558 | /// %Assignment disabled | |
1559 | Def_Testcase& operator=(const Def_Testcase& p); | |
1560 | public: | |
1561 | Def_Testcase(Identifier *p_id, FormalParList *p_fpl, | |
1562 | Reference *p_runs_on_ref, Reference *p_system_ref, | |
1563 | StatementBlock *p_block); | |
1564 | virtual ~Def_Testcase(); | |
1565 | virtual Def_Testcase *clone() const; | |
1566 | virtual void set_fullname(const string& p_fullname); | |
1567 | virtual void set_my_scope(Scope *p_scope); | |
1568 | virtual Type *get_RunsOnType(); | |
1569 | Type *get_SystemType(); | |
1570 | virtual FormalParList *get_FormalParList(); | |
1571 | /** Returns a scope that can access the definitions within component type | |
1572 | * \a comptype and its parent is \a parent_scope.*/ | |
1573 | RunsOnScope *get_runs_on_scope(Type *comptype); | |
1574 | virtual void chk(); | |
1575 | virtual void generate_code(output_struct *target, bool clean_up = false); | |
1576 | virtual void generate_code(CodeGenHelper& cgh); | |
1577 | virtual void dump_internal(unsigned level) const; | |
1578 | ||
1579 | virtual void set_parent_path(WithAttribPath* p_path); | |
1580 | }; | |
1581 | ||
1582 | /** General class to represent formal parameters. The inherited | |
1583 | * attribute asstype carries the kind and direction of the | |
1584 | * parameter. */ | |
1585 | class FormalPar : public Definition { | |
1586 | private: | |
1587 | Type *type; | |
1588 | /** Default value of the parameter (optional). If \a checked flag is true | |
1589 | * then field \a ap is used otherwise \a ti is active. */ | |
1590 | union { | |
1591 | TemplateInstance *ti; | |
1592 | ActualPar *ap; | |
1593 | } defval; | |
1594 | /** Points to the formal parameter list that \a this belongs to. */ | |
1595 | FormalParList *my_parlist; | |
1596 | /** Flag that indicates whether the value of the parameter is overwritten | |
1597 | * within the function/altstep/testcase body. | |
1598 | * Used only in case of `in' value or template parameters. */ | |
1599 | bool used_as_lvalue; | |
1600 | /** restriction on template value */ | |
1601 | template_restriction_t template_restriction; | |
1602 | /** normal or lazy evaluation parametrization should be used */ | |
1603 | bool lazy_eval; | |
51fa56b9 | 1604 | /** Flag that indicates whether the C++ code for the parameter's default |
1605 | * value has been generated or not. */ | |
1606 | bool defval_generated; | |
3f84031e | 1607 | /** Flag that indicates whether the parameter is used in the function/ |
1608 | * altstep/testcase/parameterized template body. */ | |
1609 | bool usage_found; | |
970ed795 EL |
1610 | |
1611 | /// Copy constructor disabled | |
1612 | FormalPar(const FormalPar& p); | |
1613 | /// %Assignment disabled | |
1614 | FormalPar& operator=(const FormalPar& p); | |
1615 | public: | |
1616 | FormalPar(asstype_t p_asstype, Type *p_type, Identifier* p_name, | |
1617 | TemplateInstance *p_defval, bool p_lazy_eval=false); | |
1618 | FormalPar(asstype_t p_asstype, | |
1619 | template_restriction_t p_template_restriction, | |
1620 | Type *p_type, Identifier* p_name, TemplateInstance *p_defval, | |
1621 | bool p_lazy_eval=false); | |
1622 | FormalPar(asstype_t p_asstype, Identifier* p_name, | |
1623 | TemplateInstance *p_defval); | |
1624 | ~FormalPar(); | |
1625 | virtual FormalPar *clone() const; | |
1626 | virtual void set_fullname(const string& p_fullname); | |
1627 | virtual void set_my_scope(Scope *p_scope); | |
1628 | /** Always true. Formal parameters are considered as local definitions | |
1629 | * even if their scope is the module definitions. */ | |
1630 | virtual bool is_local() const; | |
1631 | virtual Type *get_Type(); | |
1632 | virtual void chk(); | |
1633 | bool has_defval() const; | |
1634 | bool has_notused_defval() const; | |
1635 | /** Get the default value. | |
1636 | * \pre chk() has been called (checked==true) */ | |
1637 | ActualPar *get_defval() const; | |
1638 | void set_defval(ActualPar *defpar); | |
1639 | void set_my_parlist(FormalParList *p_parlist) { my_parlist = p_parlist; } | |
1640 | FormalParList *get_my_parlist() const { return my_parlist; } | |
1641 | ActualPar *chk_actual_par(TemplateInstance *actual_par, | |
1642 | Type::expected_value_t exp_val); | |
1643 | private: | |
1644 | ActualPar *chk_actual_par_value(TemplateInstance *actual_par, | |
1645 | Type::expected_value_t exp_val); | |
1646 | ActualPar *chk_actual_par_template(TemplateInstance *actual_par, | |
1647 | Type::expected_value_t exp_val); | |
1648 | ActualPar *chk_actual_par_by_ref(TemplateInstance *actual_par, | |
1649 | bool is_template, Type::expected_value_t exp_val); | |
1650 | ActualPar *chk_actual_par_timer(TemplateInstance *actual_par, | |
1651 | Type::expected_value_t exp_val); | |
1652 | ActualPar *chk_actual_par_port(TemplateInstance *actual_par, | |
1653 | Type::expected_value_t exp_val); | |
1654 | public: | |
1655 | /** Checks whether the value of the parameter may be modified in the body | |
1656 | * of the parameterized definition (in assignment, port redirect or passing | |
1657 | * it further as 'out' or 'inout' parameter). Applicable to `in' value or | |
1658 | * template parameters only. Note that formal parameters of templates cannot | |
1659 | * be modified. If the modification is allowed a flag is set, which is | |
1660 | * considered at C++ code generation. Argument \a p_loc is used for error | |
1661 | * reporting. */ | |
1662 | virtual void use_as_lvalue(const Location& p_loc); | |
1663 | bool get_used_as_lvalue() const { return used_as_lvalue; } | |
51fa56b9 | 1664 | /** Partially generates the C++ object that represents the default value for |
1665 | * the parameter (if present). The object's declaration is not generated, | |
1666 | * only its value assignment. */ | |
1667 | char* generate_code_defval(char* str); | |
1668 | /** Generates the C++ object that represents the default value for the | |
970ed795 EL |
1669 | * parameter (if present). */ |
1670 | virtual void generate_code_defval(output_struct *target, bool clean_up = false); | |
1671 | /** Generates the C++ equivalent of the formal parameter, appends it to | |
3f84031e | 1672 | * \a str and returns the resulting string. |
1673 | * The name of the parameter is not displayed if the parameter is unused | |
1674 | * (unless forced). | |
1675 | * @param display_unused forces the display of the parameter name */ | |
1676 | char *generate_code_fpar(char *str, bool display_unused = false); | |
970ed795 EL |
1677 | /** Generates a C++ statement that defines an object (variable) for the |
1678 | * formal parameter, appends it to \a str and returns the resulting | |
1679 | * string. The name of the object is constructed from \a p_prefix and the | |
1680 | * parameter identifier. | |
1681 | * The \a refch parameter is needed when the code for start_ptc_function is | |
1682 | * generated, because reference is generated in case of inout parameters. */ | |
1683 | char *generate_code_object(char *str, const char *p_prefix, | |
1684 | char refch = '&'); | |
1685 | /** Generates a C++ statement that instantiates a shadow object for the | |
1686 | * parameter when necessary. It is used when the value of an 'in' value or | |
1687 | * template parameter is overwritten within the function body. */ | |
1688 | char *generate_shadow_object(char *str) const; | |
1689 | /** Generates a C++ statement that calls a function that sets the parameter unbound | |
1690 | * It is used when the value of an 'out' value */ | |
1691 | char *generate_code_set_unbound(char *str) const; | |
1692 | virtual void dump_internal(unsigned level) const; | |
1693 | template_restriction_t get_template_restriction() | |
1694 | { return template_restriction; } | |
1695 | virtual bool get_lazy_eval() const { return lazy_eval; } | |
1696 | // code generation: get the C++ string that refers to the formal parameter | |
1697 | // adds a casting to data type if wrapped into a lazy param | |
3f84031e | 1698 | string get_reference_name(Scope* scope) const; |
1699 | /** Indicates that the parameter is used at least once. */ | |
1700 | void set_usage_found() { usage_found = true; } | |
970ed795 EL |
1701 | }; |
1702 | ||
1703 | /** Class to represent a list of formal parameters. Owned by a | |
1704 | * Def_Template, Def_Function_Base, Def_Altstep or Def_Testcase. */ | |
1705 | class FormalParList : public Scope, public Location { | |
1706 | private: | |
1707 | vector<FormalPar> pars_v; | |
1708 | /** Map names to the formal parameters in pars_v. Filled by | |
1709 | * FormalParList::chk*/ | |
1710 | map<string, FormalPar> pars_m; | |
1711 | /** Indicates the minimal number of actual parameters that must be present | |
1712 | * in parameterized references. Could be less than the size of pars_v | |
1713 | * if some parameters have default values. */ | |
1714 | size_t min_nof_pars; | |
1715 | /** Points to the definition that the parameter list belongs to. */ | |
1716 | Definition *my_def; | |
1717 | bool checked; | |
1718 | bool is_startable; | |
1719 | ||
1720 | /** Copy constructor. For FormalParList::clone() only. */ | |
1721 | FormalParList(const FormalParList& p); | |
1722 | /** %Assignment disallowed. */ | |
1723 | FormalParList& operator=(const FormalParList& p); | |
1724 | public: | |
1725 | FormalParList() : Scope(), Location(), pars_v(), pars_m() | |
1726 | , min_nof_pars(0), my_def(0), checked(false), is_startable(false) {} | |
1727 | ~FormalParList(); | |
1728 | virtual FormalParList *clone() const; | |
1729 | virtual void set_fullname(const string& p_fullname); | |
1730 | /** Sets the parent scope and the scope of parameters to \a p_scope. */ | |
1731 | virtual void set_my_scope(Scope *p_scope); | |
1732 | void set_my_def(Definition *p_def) { my_def = p_def; } | |
1733 | Definition *get_my_def() const { return my_def; } | |
1734 | void add_fp(FormalPar *p_fp); | |
1735 | size_t get_nof_fps() const { return pars_v.size(); } | |
1736 | bool has_notused_defval() const; | |
1737 | bool has_only_default_values() const; | |
1738 | bool has_fp_withName(const Identifier& p_name); | |
1739 | FormalPar *get_fp_byName(const Identifier& p_name); | |
1740 | FormalPar *get_fp_byIndex(size_t n) const { return pars_v[n]; } | |
1741 | bool get_startability(); | |
1742 | virtual Common::Assignment *get_ass_bySRef(Common::Ref_simple *p_ref); | |
1743 | virtual bool has_ass_withId(const Identifier& p_id); | |
1744 | /** Checks the parameter list, which belongs to definition of type | |
1745 | * \a deftype. */ | |
1746 | void chk(Definition::asstype_t deftype); | |
1747 | void chk_noLazyParams(); | |
1748 | /** Checks the parameter list for startability: reports error if the owner | |
1749 | * function cannot be started on a PTC. Used by functions and function | |
1750 | * types. Parameter \a p_what shall contain "Function" or "Function type", | |
1751 | * \a p_name shall contain the name of the function or function type. */ | |
1752 | void chk_startability(const char *p_what, const char *p_name); | |
1753 | /** Checks the compatibility of two formal parameter list. | |
1754 | * They are compatible if every parameter is compatible, has the same | |
1755 | * attribute, and name */ | |
1756 | void chk_compatibility(FormalParList* p_fp_list, const char* where); | |
1757 | /** Checks the parsed actual parameters in \a p_tis against \a this. | |
1758 | * The actual parameters that are the result of transformation are added to | |
1759 | * \a p_aplist (which is usually empty when this function is called). | |
1760 | * \return true in case of any error, false after a successful check. */ | |
1761 | bool chk_actual_parlist(TemplateInstances *p_tis, ActualParList *p_aplist); | |
1762 | /** Fold named parameters into the unnamed (order-based) param list. | |
1763 | * | |
1764 | * Named parameters are checked against the formal parameters. | |
1765 | * Found ones are transferred into the unnamed param list at the | |
1766 | * appropriate index. | |
1767 | * | |
1768 | * @param p_paps actual parameters from the parser (Bison); contains | |
1769 | * both named and unnamed parameters | |
1770 | * @param p_aplist actual parameters | |
1771 | * @return the result of calling chk_actual_parlist, above: | |
1772 | * true if error, false if the check is successful | |
1773 | */ | |
1774 | bool fold_named_and_chk(ParsedActualParameters *p_paps, ActualParList *p_aplist); | |
1775 | bool chk_activate_argument(ActualParList *p_aplist, | |
1776 | const char* p_description); | |
1777 | void set_genname(const string& p_prefix); | |
1778 | /** Generates the C++ equivalent of the formal parameter list, appends it | |
3f84031e | 1779 | * to \a str and returns the resulting string. |
1780 | * The names of unused parameters are not displayed (unless forced). | |
1781 | * @param display_unused forces the display of parameter names (an amount | |
1782 | * equal to this parameter are forced, starting from the first) */ | |
1783 | char *generate_code(char *str, size_t display_unused = 0); | |
51fa56b9 | 1784 | /** Partially generates the C++ objects that represent the default value for |
1785 | * the parameters (if present). The objects' declarations are not generated, | |
1786 | * only their value assignments. */ | |
1787 | char* generate_code_defval(char* str); | |
970ed795 EL |
1788 | /** Generates the C++ objects that represent the default values for the |
1789 | * parameters (if present). */ | |
1790 | void generate_code_defval(output_struct *target); | |
1791 | /** Generates a C++ actual parameter list for wrapper functions, appends it | |
1792 | * to \a str and returns the resulting string. It contains the | |
1793 | * comma-separated list of parameter identifiers prefixed by \a p_prefix. */ | |
1794 | char *generate_code_actual_parlist(char *str, const char *p_prefix); | |
1795 | /** Generates a C++ code sequence that defines an object (variable) for | |
1796 | * each formal parameter (which is used in wrapper functions), appends it | |
1797 | * to \a str and returns the resulting string. The name of each object is | |
1798 | * constructed from \a p_prefix and the parameter identifier. | |
1799 | * The \a refch parameter is needed when the code for start_ptc_function is | |
1800 | * generated, because reference is generated in case of inout parameters. */ | |
1801 | char *generate_code_object(char *str, const char *p_prefix, | |
1802 | char refch = '&'); | |
1803 | /** Generates the C++ shadow objects for all parameters. */ | |
1804 | char *generate_shadow_objects(char *str) const; | |
1805 | char *generate_code_set_unbound(char *str) const; | |
1806 | void dump(unsigned level) const; | |
1807 | }; | |
1808 | ||
1809 | } // namespace Ttcn | |
1810 | ||
1811 | #endif // _Ttcn_AST_HH |