Commit | Line | Data |
---|---|---|
970ed795 EL |
1 | /////////////////////////////////////////////////////////////////////////////// |
2 | // Copyright (c) 2000-2014 Ericsson Telecom AB | |
3 | // All rights reserved. This program and the accompanying materials | |
4 | // are made available under the terms of the Eclipse Public License v1.0 | |
5 | // which accompanies this distribution, and is available at | |
6 | // http://www.eclipse.org/legal/epl-v10.html | |
7 | /////////////////////////////////////////////////////////////////////////////// | |
8 | #ifndef _Common_Setting_HH | |
9 | #define _Common_Setting_HH | |
10 | ||
11 | #include <stdio.h> | |
12 | ||
13 | #include "error.h" | |
14 | #include "string.hh" | |
15 | #include "stack.hh" | |
16 | #include "vector.hh" | |
17 | #include "map.hh" | |
18 | ||
19 | /** YYLTYPE definition from compiler.tab.hh , used by Location class */ | |
20 | #if ! defined (YYLTYPE) && ! defined (YYLTYPE_IS_DECLARED) | |
21 | typedef struct YYLTYPE | |
22 | { | |
23 | int first_line; | |
24 | int first_column; | |
25 | int last_line; | |
26 | int last_column; | |
27 | } YYLTYPE; | |
28 | # define YYLTYPE_IS_DECLARED 1 | |
29 | # define YYLTYPE_IS_TRIVIAL 1 | |
30 | #endif | |
31 | ||
32 | struct expression_struct_t; | |
33 | ||
34 | namespace Ttcn { | |
35 | // not defined here | |
36 | class FieldOrArrayRef; | |
37 | class FieldOrArrayRefs; | |
38 | class ActualParList; | |
39 | class RunsOnScope; | |
40 | class StatementBlock; | |
41 | struct ErroneousDescriptor; | |
42 | class transparency_holder; | |
43 | } // namespace Ttcn | |
44 | ||
45 | namespace Common { | |
46 | ||
47 | /** | |
48 | * \addtogroup AST | |
49 | * | |
50 | * @{ | |
51 | */ | |
52 | ||
53 | class Node; | |
54 | class StringRepr; | |
55 | class Setting; | |
56 | class Governor; | |
57 | class Governed; | |
58 | class GovdSet; | |
59 | ||
60 | class Scope; | |
61 | ||
62 | class Reference; | |
63 | class Ref_simple; | |
64 | class ReferenceChain; | |
65 | ||
66 | // not defined here | |
67 | class Identifier; | |
68 | class Module; | |
69 | class Assignment; | |
70 | class Assignments; | |
71 | class Type; | |
72 | class Value; | |
73 | ||
74 | /** | |
75 | * Base class for the AST-classes that have associated location | |
76 | * (file name and line number) information. | |
77 | * | |
78 | * This class correctly uses the compiler-generated copy constructor | |
79 | * and assignment operator, despite having a pointer member. | |
80 | */ | |
81 | class Location { | |
82 | private: | |
83 | /** map used as set containing one instance of all file names | |
84 | * encountered during preprocessing. | |
85 | * It is used as long term storage for the filename extracted from | |
86 | * C preprocessor line markers (#line directives) */ | |
87 | static map<string,void> *source_file_names; | |
88 | /** Source file name. | |
89 | * Not owned by the Location object. Do not delete. | |
90 | */ | |
91 | const char *filename; | |
92 | /** Source file location. | |
93 | * Line and column for start and end (some of which may be zero) | |
94 | */ | |
95 | YYLTYPE yyloc; /* yyloc.first_line == lineno for backward compatibility */ | |
96 | /** The location is inside a function with extension "transparent" */ | |
97 | static bool transparency; | |
98 | friend class Ttcn::transparency_holder; | |
99 | public: | |
100 | ||
101 | /** adds new file name, returns pointer to stored file name, | |
102 | * names are stored only once */ | |
103 | static const char* add_source_file_name(const string& file_name); | |
104 | static void delete_source_file_names(); | |
105 | ||
106 | /** Default constructor. | |
107 | * Sets everything to 0/NULL. | |
108 | */ | |
109 | Location(); | |
110 | ||
111 | /** Constructor with filename and just a line number. | |
112 | * Sets \c yyloc.first_line and \c yyloc.last_line to \p p_lineno, | |
113 | * and the columns to zero. */ | |
114 | Location(const char *p_filename, int p_lineno=0) | |
115 | { set_location(p_filename, p_lineno); } | |
116 | ||
117 | /** Constructor with filename and full location information. | |
118 | * Copies \p p_yyloc into \p yyloc. | |
119 | */ | |
120 | Location(const char *p_filename, const YYLTYPE& p_yyloc) | |
121 | { set_location(p_filename, p_yyloc); } | |
122 | ||
123 | /** Constructor with filename and two location info. | |
124 | * | |
125 | * @param p_filename | |
126 | * @param p_firstloc holds the location of the beginning. | |
127 | * Its \p first_line and \p first_column are copied into | |
128 | * \c yyloc.first_line and \c yyloc.first_column. | |
129 | * @param p_lastloc contains the location of the end. | |
130 | * Its \p last_line and \p last_column are copied into | |
131 | * \c yyloc.last_line and \c yyloc.last_column. | |
132 | */ | |
133 | Location(const char *p_filename, const YYLTYPE& p_firstloc, | |
134 | const YYLTYPE& p_lastloc) | |
135 | { set_location(p_filename, p_firstloc, p_lastloc); } | |
136 | ||
137 | /** Constructor with filename and full location available separately. | |
138 | * Stores the filename, and the line/column info in the appropriate | |
139 | * members of \c yyloc. | |
140 | */ | |
141 | Location(const char *p_filename, int p_first_line, int p_first_column, | |
142 | int p_last_line, int p_last_column) | |
143 | { set_location(p_filename, p_first_line, p_first_column, | |
144 | p_last_line, p_last_column); } | |
145 | ||
146 | /** Setter with filename and full location information. | |
147 | * Copies \p p_yyloc into \p yyloc. | |
148 | */ | |
149 | void set_location(const char *p_filename, int p_lineno=0); | |
150 | /** Setter with filename and full location information. | |
151 | * Copies \p p_yyloc into \p yyloc. | |
152 | */ | |
153 | void set_location(const char *p_filename, const YYLTYPE& p_yyloc); | |
154 | /** Setter with filename and two location info. | |
155 | * | |
156 | * @param p_filename | |
157 | * @param p_firstloc holds the location of the beginning. | |
158 | * Its \p first_line and \p first_column are copied into | |
159 | * \c yyloc.first_line and \c yyloc.first_column. | |
160 | * @param p_lastloc contains the location of the end. | |
161 | * Its \p last_line and \p last_column are copied into | |
162 | * \c yyloc.last_line and \c yyloc.last_column. | |
163 | */ | |
164 | void set_location(const char *p_filename, const YYLTYPE& p_firstloc, | |
165 | const YYLTYPE& p_lastloc); | |
166 | /** Setter with filename and full location available separately. | |
167 | * Stores the filename, and the line/column info in the appropriate | |
168 | * members of \c yyloc. | |
169 | */ | |
170 | void set_location(const char *p_filename, int p_first_line, | |
171 | int p_first_column, int p_last_line, int p_last_column); | |
172 | ||
173 | /** Copies the stored location information from \a p. */ | |
174 | void set_location(const Location& p) { *this = p; } | |
175 | ||
176 | /** Joins the coordinates of adjacent location \a p into this. */ | |
177 | void join_location(const Location& p); | |
178 | ||
179 | /** Returns the attribute filename. */ | |
180 | const char *get_filename() const { return filename; } | |
181 | /** Returns the line number, for backward compatibility */ | |
182 | int get_lineno() const { return yyloc.first_line; } | |
183 | /** Returns the first line attribute */ | |
184 | int get_first_line() const { return yyloc.first_line; } | |
185 | /** Returns the last line attribute */ | |
186 | int get_last_line() const { return yyloc.last_line; } | |
187 | /** Returns the first column attribute */ | |
188 | int get_first_column() const { return yyloc.first_column; } | |
189 | /** Returns the last column attribute */ | |
190 | int get_last_column() const { return yyloc.last_column; } | |
191 | ||
192 | private: | |
193 | /** Prints the line/column information stored in \a this into file \a fp. | |
194 | * Used by functions print_location() */ | |
195 | void print_line_info(FILE *fp) const; | |
196 | public: | |
197 | /** Prints the contents of \a this into file \a fp. Used in error | |
198 | * messages */ | |
199 | void print_location(FILE *fp) const; | |
200 | ||
201 | /** Generic error reporting function with printf-like arguments. */ | |
202 | void error(const char *fmt, ...) const | |
203 | __attribute__ ((__format__ (__printf__, 2, 3))); | |
204 | /** Generic warning function with printf-like arguments. */ | |
205 | void warning(const char *fmt, ...) const | |
206 | __attribute__ ((__format__ (__printf__, 2, 3))); | |
207 | /** Generic note function with printf-like arguments. */ | |
208 | void note(const char *fmt, ...) const | |
209 | __attribute__ ((__format__ (__printf__, 2, 3))); | |
210 | ||
211 | /** Generates a C++ code fragment that instantiates a runtime location | |
212 | * object containing the file name and source line information carried by | |
213 | * \a this. The C++ code is appended to argument \a str and the resulting | |
214 | * string is returned. Arguments \a entitytype and \a entityname determine | |
215 | * the attributes of the location object based on the kind (FUNCTION, | |
216 | * TESTCASE, etc.) and name of the corresponding TTCN-3 definition. | |
217 | * The generation of location objects is optional, it is controlled by a | |
218 | * command line switch. */ | |
219 | char *create_location_object(char *str, const char *entitytype, | |
220 | const char *entityname) const; | |
221 | /** Generates a C++ code fragment that updates the line number information | |
222 | * of the innermost runtime location object. The C++ code is appended to | |
223 | * argument \a str and the resulting string is returned. The function is | |
224 | * used by subsequent statements of statement blocks. */ | |
225 | char *update_location_object(char *str) const; | |
226 | }; | |
227 | ||
228 | /** | |
229 | * Base class for AST-classes. | |
230 | * | |
231 | * The AST is an example of the Composite pattern ("Design Patterns", by | |
232 | * Gamma et al.): it represents a part-whole hierarchy and allows clients | |
233 | * to treat individual objects and compositions of objects uniformly. | |
234 | * | |
235 | * A container node "distributes" method calls to its subordinates: | |
236 | * | |
237 | * Common::Modules contains a collection of Asn/Ttcn::Module objects. | |
238 | * Common::Modules::generate_code() calls Common::Module::generate_code() | |
239 | * for each module that was parsed. Common::Module::generate_code() calls | |
240 | * the virtual generate_code_internal(); for a TTCN-3 module this is | |
241 | * Ttcn::Module::generate_code_internal(). | |
242 | * | |
243 | * A Ttcn::Module contains (among others) imports, definitions and (maybe) | |
244 | * a control part. Consequently Ttcn::Module::generate_code_internal() calls | |
245 | * Ttcn::Imports::generate_code(), then Ttcn::Definitions::generate_code(), | |
246 | * then (maybe) Ttcn::ControlPart::generate_code(). | |
247 | */ | |
248 | class Node { | |
249 | private: | |
250 | /** To detect missing/duplicated invoking of destructor. */ | |
251 | static int counter; | |
252 | #ifdef MEMORY_DEBUG | |
253 | /** Linked list for tracking undeleted nodes. */ | |
254 | Node *prev_node, *next_node; | |
255 | #endif | |
256 | /** Name that contains information about the node's position in | |
257 | * the AST. It is used when reporting things to the user. | |
258 | * Guidelines for names can be found in X.680 clause 14. Main | |
259 | * rules: components are separated by dot ("."). Absolute names | |
260 | * begin with "@" followed by the module name. | |
261 | */ | |
262 | string fullname; | |
263 | protected: // Setting needs access to the constructors | |
264 | /** Default constructor. */ | |
265 | Node(); | |
266 | /** The copy constructor. */ | |
267 | Node(const Node& p); | |
268 | private: | |
269 | /** Assignment disabled */ | |
270 | Node& operator=(const Node& p); | |
271 | public: | |
272 | /** | |
273 | * "Virtual constructor". | |
274 | * | |
275 | * In AST-classes, you should invoke the clone() member | |
276 | * explicitly, instead of using the copy constructor. | |
277 | * | |
278 | * \note The clone is not an exact copy of the original object. | |
279 | * Some information (like cached things, links to parent etc., if | |
280 | * any) are not copied; they are updated when adding to parent | |
281 | * node, checking the value etc. | |
282 | */ | |
283 | virtual Node* clone() const = 0; | |
284 | /** The destructor. */ | |
285 | virtual ~Node(); | |
286 | /** Gives an error message if counter is not zero. It can be | |
287 | * invoked before the program exits (like check_mem_leak()) to | |
288 | * verify that all AST-objects are destroyed. */ | |
289 | static void chk_counter(); | |
290 | /** Sets the fullname. In the descendant classes, it sets also the | |
291 | * fullname of the node's children, if any. */ | |
292 | virtual void set_fullname(const string& p_fullname); | |
293 | /** Gets the fullname. */ | |
294 | const string& get_fullname() const { return fullname; } | |
295 | virtual void set_my_scope(Scope *p_scope); | |
296 | virtual void dump(unsigned level) const; | |
297 | }; | |
298 | ||
299 | /** | |
300 | * Class Setting. ObjectClass, Object, ObjectSet, Type, Value or | |
301 | * ValueSet. | |
302 | */ | |
303 | class Setting : public Node, public Location { | |
304 | public: | |
305 | enum settingtype_t { | |
306 | S_UNDEF, /**< Reference to non-existent stuff */ | |
307 | S_ERROR, /**< Reference to non-existent stuff */ | |
308 | S_OC, /**< ObjectClass */ | |
309 | S_T, /**< Type */ | |
310 | S_TEMPLATE, /**< Template */ | |
311 | S_O, /**< Object */ | |
312 | S_V, /**< Value */ | |
313 | S_OS, /**< ObjectSet */ | |
314 | S_VS /**< ValueSet */ | |
315 | }; | |
316 | protected: // Governed and Governor need access to members and copy c-tor | |
317 | settingtype_t st; | |
318 | Scope *my_scope; | |
319 | string genname; | |
320 | bool checked; | |
321 | /** Indicates whether the circular references within embedded entities | |
322 | * has been checked. For instance: a record/SEQUENCE type cannot contain | |
323 | * itself as a mandatory field; a field in a value cannot refer to the | |
324 | * value itself. */ | |
325 | bool recurs_checked; | |
326 | ||
327 | Setting(const Setting& p) | |
328 | : Node(p), Location(p), st(p.st), my_scope(0), | |
329 | genname(), checked(false), recurs_checked(false) {} | |
330 | private: | |
331 | /** Assignment disabled */ | |
332 | Setting& operator=(const Setting& p); | |
333 | public: | |
334 | Setting(settingtype_t p_st); | |
335 | virtual Setting* clone() const = 0; | |
336 | settingtype_t get_st() const { return st; } | |
337 | virtual void set_my_scope(Scope *p_scope); | |
338 | Scope *get_my_scope() const { return my_scope; } | |
339 | /** Returns whether the setting was defined in ASN.1 module. */ | |
340 | bool is_asn1() const; | |
341 | /** Returns a unique temporary C++ identifier, which is obtained from | |
342 | * the module scope. */ | |
343 | string get_temporary_id() const; | |
344 | /** Set \a genname from \p p_genname. | |
345 | * | |
346 | * @pre p_genname must not be empty. */ | |
347 | void set_genname(const string& p_genname); | |
348 | /** Set \a genname from two parts. | |
349 | * | |
350 | * Basically concatenates \p p_prefix, an underscore and \p p_suffix, | |
351 | * unless p_prefix already ends with, or p_suffix already begins with | |
352 | * \b precisely one underscore. | |
353 | * | |
354 | * @pre p_prefix must not be empty. | |
355 | * @pre p_suffix must not be empty. */ | |
356 | void set_genname(const string& p_prefix, const string& p_suffix); | |
357 | public: | |
358 | /** Returns a C++ reference that points to the C++ equivalent of this | |
359 | * setting from the local module (when such entity exists) */ | |
360 | const string& get_genname_own() const; | |
361 | /** Returns a C++ reference that points to this setting from the module of | |
362 | * scope \a p_scope */ | |
363 | string get_genname_own(Scope *p_scope) const; | |
364 | ||
365 | private: | |
366 | /** Creates and returns the string representation of the setting. */ | |
367 | virtual string create_stringRepr(); | |
368 | public: | |
369 | /** Returns the string representation of the setting. Currently it calls | |
370 | * \a create_stringRepr(), but it may use some caching in the future. */ | |
371 | string get_stringRepr() { return create_stringRepr(); } | |
372 | }; | |
373 | ||
374 | /** | |
375 | * Ass_Error::get_Setting() returns this. | |
376 | */ | |
377 | class Setting_Error : public Setting { | |
378 | private: | |
379 | Setting_Error(const Setting_Error& p) : Setting(p) {} | |
380 | public: | |
381 | Setting_Error() : Setting(S_ERROR) {} | |
382 | virtual Setting_Error* clone() const; | |
383 | }; | |
384 | ||
385 | /** | |
386 | * Things that can be the governor of something. | |
387 | */ | |
388 | class Governor : public Setting { | |
389 | protected: // Derived classes need access to the copy c-tor | |
390 | Governor(const Governor& p) : Setting(p) {} | |
391 | public: | |
392 | Governor(settingtype_t p_st) : Setting(p_st) {} | |
393 | virtual Governor* clone() const =0; | |
394 | virtual void chk() =0; | |
395 | }; | |
396 | ||
397 | /** | |
398 | * Things that have a governor. Object, Value... | |
399 | */ | |
400 | class Governed : public Setting { | |
401 | protected: // Derived classes need access to the copy c-tor | |
402 | Governed(const Governed& p) : Setting(p) {} | |
403 | public: | |
404 | Governed(settingtype_t p_st) : Setting(p_st) {} | |
405 | virtual Governed* clone() const =0; | |
406 | virtual Governor* get_my_governor() const =0; | |
407 | }; | |
408 | ||
409 | /** | |
410 | * A governed thing that will be mapped to a C++ entity. | |
411 | * (e.g. Value, Template) | |
412 | */ | |
413 | class GovernedSimple : public Governed { | |
414 | public: | |
415 | enum code_section_t { | |
416 | CS_UNKNOWN, /**< Unknown (i.e. not specified). */ | |
417 | CS_PRE_INIT, /**< Initialized before processing the configuration file | |
418 | * (i.e. module parameters are not known). Example: | |
419 | * constants, default value for module parameters. */ | |
420 | CS_POST_INIT, /**< Initialized after processing the configuration file | |
421 | * (i.e. module parameters are known). Example: | |
422 | * non-parameterized templates. */ | |
423 | CS_INIT_COMP, /**< Initialized with the component entities (i.e. when | |
424 | * the component type is known). Example: initial value | |
425 | * for component variables, default duration for timers. */ | |
426 | CS_INLINE /**< Initialized immediately at the place of definition. | |
427 | * Applicable to local definitions only. Example: initial | |
428 | * value for a local variable. */ | |
429 | }; | |
430 | private: | |
431 | /** A prefix that shall be inserted before the genname when initializing | |
432 | * the C++ object. Without this prefix the genname points to a read-only | |
433 | * C++ object reference. For example, `const_c1' is a writable object with | |
434 | * limited access (file static), but `c1' is a global const reference | |
435 | * pointing to it. | |
436 | * Possible values: "const_", "modulepar_", "template_". | |
437 | */ | |
438 | const char *genname_prefix; | |
439 | /** Indicates the section of the output code where the initializer C++ | |
440 | * sequence has to be put. If entity A refers to entity B and both has to | |
441 | * be initialized in the same section, the initializer of B must precede | |
442 | * the initializer of A. If the initializer of A and B has to be put into | |
443 | * different sections the right order is provided automatically by the | |
444 | * run-time environment. */ | |
445 | code_section_t code_section; | |
446 | /** A flag that indicates whether the initializer C++ code has been | |
447 | * generated for the object (or object field). | |
448 | */ | |
449 | bool code_generated; | |
450 | protected: // Derived classes need access to the copy c-tor | |
451 | Ttcn::ErroneousDescriptor* err_descr; // not owned, used by negative testing | |
452 | GovernedSimple(const GovernedSimple& p) : Governed(p), | |
453 | genname_prefix(p.genname_prefix), code_section(p.code_section), | |
454 | code_generated(false), err_descr(NULL), needs_conversion(false) { } | |
455 | bool needs_conversion; /**< Type conversion needed. */ | |
456 | private: | |
457 | /** Assignment disabled */ | |
458 | GovernedSimple& operator=(const GovernedSimple& p); | |
459 | public: | |
460 | GovernedSimple(settingtype_t p_st) : Governed(p_st), genname_prefix(0), | |
461 | code_section(CS_UNKNOWN), code_generated(false), err_descr(NULL), | |
462 | needs_conversion(false) { } | |
463 | ||
464 | /** Sets attribute \a genname_prefix to \a p_genname_prefix. For efficiency | |
465 | * reasons the string itself is not copied, thus it must point to a | |
466 | * permanent memory area. */ | |
467 | void set_genname_prefix(const char *p_genname_prefix) | |
468 | { genname_prefix = p_genname_prefix; } | |
469 | /** Returns attribute \a genname_prefix. */ | |
470 | const char *get_genname_prefix() const { return genname_prefix; } | |
471 | ||
472 | /** Returns the attribute \a code_section. */ | |
473 | code_section_t get_code_section() const { return code_section; } | |
474 | /** Sets the attribute \a code_section to \a p_code_section. */ | |
475 | void set_code_section(code_section_t p_code_section) | |
476 | { code_section = p_code_section; } | |
477 | ||
478 | /** Returns the flag \a code_generated. */ | |
479 | bool get_code_generated() const { return code_generated; } | |
480 | /** Sets the flag \a code_generated to true. */ | |
481 | void set_code_generated() { code_generated = true; } | |
482 | ||
483 | /** Sets the err_descr if the template or value has negative testing */ | |
484 | void set_err_descr(Ttcn::ErroneousDescriptor* p_err_descr) | |
485 | { err_descr = p_err_descr; } | |
486 | Ttcn::ErroneousDescriptor* get_err_descr() const | |
487 | { return err_descr; } | |
488 | ||
489 | /** has_single_expr() to return false. */ | |
490 | inline void set_needs_conversion() { needs_conversion = true; } | |
491 | inline bool get_needs_conversion() const { return needs_conversion; } | |
492 | ||
493 | /** Returns the C++ expression that refers to the object, which has to be | |
494 | * initialized. */ | |
495 | string get_lhs_name() const; | |
496 | ||
497 | /** Returns whether the C++ initialization sequence of \a refd must be | |
498 | * inserted before the initialization sequence of \a this. The function is | |
499 | * used when \a this refers to \a refd. | |
500 | * It returns true if all the following conditions apply: | |
501 | * 1) Code has not been generated for \a refd. | |
502 | * 2) Both \a this and \a refd are defined in the same module. | |
503 | * 3) The initialization sequence for both shall be placed into the same | |
504 | * code section. */ | |
505 | bool needs_init_precede(const GovernedSimple *refd) const; | |
506 | /** Returns whether the entity is a top-level one (i.e. it is not embedded | |
507 | * into another entity). The function examines whether the genname is a | |
508 | * single identifier or not. */ | |
509 | bool is_toplevel() const; | |
510 | }; | |
511 | ||
512 | /** | |
513 | * A set of governed stuff. ObjectSet or ValueSet. | |
514 | */ | |
515 | class GovdSet : public Governed { | |
516 | protected: // Asn::ObjectSet needs access | |
517 | GovdSet(const GovdSet& p) : Governed(p) {} | |
518 | public: | |
519 | GovdSet(settingtype_t p_st) : Governed(p_st) {} | |
520 | virtual GovdSet* clone() const =0; | |
521 | }; | |
522 | ||
523 | /** | |
524 | * An interface-class to represent scopes of references. A scope | |
525 | * is an entity from which assignments can be seen; each of these | |
526 | * assignments can be referred by a Reference. | |
527 | */ | |
528 | class Scope : public Node { | |
529 | protected: // Several derived classes need access | |
530 | /** Link to the parent in the scope hierarchy. Can be 0 | |
531 | * (root-node, in case of the Module scope). */ | |
532 | Scope *parent_scope; | |
533 | /** Some special kind of parent. Used only in conjunction with | |
534 | * ASN.1 parameterized references. */ | |
535 | Scope *parent_scope_gen; | |
536 | ||
537 | /** The name of the scope. */ | |
538 | string scope_name; | |
539 | ||
540 | /** The name of the scope | |
541 | * as it should be reported by the __SCOPE__ macro. */ | |
542 | string scopeMacro_name; | |
543 | ||
544 | Scope(const Scope& p) | |
545 | : Node(p), parent_scope(0), parent_scope_gen(0), scope_name(), | |
546 | scopeMacro_name() {} | |
547 | private: | |
548 | /** Assignment disabled */ | |
549 | Scope& operator=(const Scope& p); | |
550 | public: | |
551 | Scope() : Node(), parent_scope(0), parent_scope_gen(0), scope_name(), | |
552 | scopeMacro_name() {} | |
553 | ||
554 | /** Sets the parent_scope to the given value. */ | |
555 | void set_parent_scope(Scope *p_parent_scope) | |
556 | { parent_scope = p_parent_scope; } | |
557 | /** Sets some othe parent scope. | |
558 | * Only called from Ref_pard::get_ref_defd_simple */ | |
559 | void set_parent_scope_gen(Scope *p_parent_scope_gen) | |
560 | { parent_scope_gen = p_parent_scope_gen; } | |
561 | /** Returns the parent_scope or NULL. */ | |
562 | Scope *get_parent_scope() const { return parent_scope; } | |
563 | /** Sets the name of the scope. */ | |
564 | void set_scope_name(const string& p_scope_name) | |
565 | { scope_name = p_scope_name; } | |
566 | /** Gets the full-qualified name of the scope. */ | |
567 | string get_scope_name() const; | |
568 | /** Sets the name of the scope. */ | |
569 | void set_scopeMacro_name(const string& p_scopeMacro_name) | |
570 | { scopeMacro_name = p_scopeMacro_name; } | |
571 | /** Gets the full-qualified name of the scope. */ | |
572 | virtual string get_scopeMacro_name() const; | |
573 | /** Returns the closest statementblock unit of the hierarchy, or null if the actual scope is not within a | |
574 | * statementblock scope. */ | |
575 | virtual Ttcn::StatementBlock *get_statementblock_scope(); | |
576 | /** Returns the scope unit of the hierarchy that belongs to a | |
577 | * 'runs on' clause. */ | |
578 | virtual Ttcn::RunsOnScope *get_scope_runs_on(); | |
579 | /** Returns the assignments/module definitions scope. */ | |
580 | virtual Assignments *get_scope_asss(); | |
581 | /** Gets the module scope. This function returns this scope or a | |
582 | * scope above this or executes FATAL_ERROR if neither is a | |
583 | * Module. */ | |
584 | virtual Module* get_scope_mod(); | |
585 | virtual Module* get_scope_mod_gen(); | |
586 | /** Returns the assignment referenced by \a p_ref. If no such | |
587 | * node, 0 is returned. */ | |
588 | virtual Assignment* get_ass_bySRef(Ref_simple *p_ref) =0; | |
589 | /** Returns whether the current scope (or its parent) has an | |
590 | * assignment with the given \a p_id. Imported symbols are not | |
591 | * searched. */ | |
592 | virtual bool has_ass_withId(const Identifier& p_id); | |
593 | virtual bool is_valid_moduleid(const Identifier& p_id); | |
594 | /** Returns the TTCN-3 component type that is associated with | |
af710487 | 595 | * keywords 'mtc' or 'system'. Returns NULL if the component type |
596 | * cannot be determined (i.e. outside testcase definitions). */ | |
597 | virtual Type *get_mtc_system_comptype(bool is_system); | |
970ed795 EL |
598 | /** Checks the 'runs on' clause of definition \a p_ass that it can |
599 | * be called from this scope unit. Parameters \a p_loc and \a | |
600 | * p_what are used in error messages. \a p_what contains "call" or | |
601 | * "activate". */ | |
602 | void chk_runs_on_clause(Assignment *p_ass, const Location& p_loc, | |
603 | const char *p_what); | |
604 | /** Checks the 'runs on' clause of type \a p_fat that the values of it can | |
605 | * be called from this scope unit. Type \a p_fat shall be of type function | |
606 | * or altstep. Parameters \a p_loc and \a p_what are used in error messages. | |
607 | * \a p_what contains "call" or "activate". */ | |
608 | void chk_runs_on_clause(Type *p_fat, const Location& p_loc, | |
609 | const char *p_what); | |
610 | }; | |
611 | ||
612 | /** | |
613 | * A Reference refers to a Setting. | |
614 | */ | |
615 | class Reference : public Node, public Location { | |
616 | protected: // Derived classes need access | |
617 | Scope *my_scope; | |
618 | bool is_erroneous; | |
619 | static size_t _Reference_counter; | |
620 | static Setting_Error *setting_error; | |
621 | ||
622 | Reference() : Node(), Location(), my_scope(0), is_erroneous(false) | |
623 | { _Reference_counter++; } | |
624 | Reference(const Reference& p) : Node(p), Location(p), my_scope(0), | |
625 | is_erroneous(p.is_erroneous) { _Reference_counter++; } | |
626 | private: | |
627 | /** Assignment disabled */ | |
628 | Reference& operator=(const Reference& p); | |
629 | public: | |
630 | virtual ~Reference(); | |
631 | virtual Reference* clone() const =0; | |
632 | /** Creates a display-name for the reference. */ | |
633 | virtual string get_dispname() =0; | |
634 | virtual void set_my_scope(Scope *p_scope); | |
635 | Scope *get_my_scope() const { return my_scope; } | |
636 | virtual bool get_is_erroneous(); | |
637 | /** Returns the referenced stuff. Returns NULL if the referenced | |
638 | * stuff does not exists. */ | |
639 | virtual Setting* get_refd_setting() =0; | |
640 | virtual Setting* get_refd_setting_error(); | |
641 | /** Returns the referred TTCN-3 definition or ASN.1 assignment. | |
642 | * If the referenced definition is not found NULL is returned after | |
643 | * reporting the error. The function ignores the TTCN-3 field or array | |
644 | * sub-references. Flag \a check_parlist indicates whether to verify the | |
645 | * actual parameter list of the TTCN-3 reference against the formal | |
646 | * parameter list of the referred definition. The parameter checking is | |
647 | * done by default, but it can be disabled in certain cases. */ | |
648 | virtual Assignment* get_refd_assignment(bool check_parlist = true) = 0; | |
649 | /** Returns the field or array subreferences of TTCN-3 references or NULL | |
650 | * otherwise. */ | |
651 | virtual Ttcn::FieldOrArrayRefs *get_subrefs(); | |
652 | /** Returns the actual parameter list for parameterized TTCN-3 references | |
653 | * or NULL otherwise. */ | |
654 | virtual Ttcn::ActualParList *get_parlist(); | |
655 | /** True if this reference refers to a settingtype \a p_st. */ | |
656 | virtual bool refers_to_st(Setting::settingtype_t p_st, | |
657 | ReferenceChain* refch=0); | |
658 | virtual bool getUsedInIsbound() {return false;} | |
659 | virtual void setUsedInIsbound() {} | |
660 | /** Returns whether the reference can be represented by an in-line C++ | |
661 | * expression. */ | |
662 | virtual bool has_single_expr() = 0; | |
663 | /** Sets the code section of embedded values (parameters, array indices). */ | |
664 | virtual void set_code_section( | |
665 | GovernedSimple::code_section_t p_code_section); | |
666 | /** Generates the C++ equivalent of the reference (including the parameter | |
667 | * list and sub-references). */ | |
668 | virtual void generate_code(expression_struct_t *expr) = 0; | |
669 | virtual void generate_code_const_ref(expression_struct_t *expr) = 0; | |
670 | virtual void dump(unsigned level) const; | |
671 | }; | |
672 | ||
673 | /** | |
674 | * Interface-class to refer to entities. %Common entities which can | |
675 | * be referred are: modules, types and values. Each simple | |
676 | * reference is formed by one or two identifiers. An optional | |
677 | * identifier identifies the module (<em>modid</em>), and another | |
678 | * the entity within that module (<em>id</em>). The \a modid is | |
679 | * optional; if present, then the reference is \a global. If not | |
680 | * present, then the identifier must be seen from the Reference's | |
681 | * Scope or one of its parent-scopes not higher (in the | |
682 | * scope-hierarchy) than a Module. | |
683 | */ | |
684 | class Ref_simple : public Reference { | |
685 | protected: // Derived classes need access | |
686 | /** Points to the referred assignment. Used for caching. */ | |
687 | Assignment *refd_ass; | |
688 | Ref_simple() : Reference(), refd_ass(0) {} | |
689 | Ref_simple(const Ref_simple& p) : Reference(p), refd_ass(0) {} | |
690 | private: | |
691 | /** Assignment disabled */ | |
692 | Ref_simple& operator=(const Ref_simple& p); | |
693 | public: | |
694 | virtual Reference* clone() const =0; | |
695 | /** Returns the \a modid, or 0 if not present. */ | |
696 | virtual const Identifier* get_modid() =0; | |
697 | /** Returns the \a id. */ | |
698 | virtual const Identifier* get_id() =0; | |
699 | /** Creates a display-name for the reference. */ | |
700 | virtual string get_dispname(); | |
701 | virtual Setting* get_refd_setting(); | |
702 | /** \param check_parlist is ignored */ | |
703 | virtual Assignment* get_refd_assignment(bool check_parlist = true); | |
704 | /** Always returns true */ | |
705 | virtual bool has_single_expr(); | |
706 | }; | |
707 | ||
708 | /** | |
709 | * Auxiliary class to detect circular references. Stores strings | |
710 | * (e.g., the display-name of the references). When adding a string, | |
711 | * checks whether it already exists. If exists, throws an | |
712 | * Error_AST_uniq with the full chain in the description. | |
713 | * | |
714 | * @note ReferenceChains should not be reused without calling reset(). | |
715 | * It's even better not to reuse them at all. | |
716 | */ | |
717 | class ReferenceChain : public Node { | |
718 | private: | |
719 | /** Stores the strings representing references. */ | |
720 | vector<string> refs; | |
721 | /** Stores a history of the length of the reference chain. | |
722 | * Used by mark_state() and prev_state(). */ | |
723 | stack<size_t> refstack; | |
724 | const Location *my_loc; | |
725 | /** Operation being performed (for error reporting) */ | |
726 | const char* err_str; | |
727 | dynamic_array<string> errors; | |
728 | /** Used to mark states of the errors array. */ | |
729 | stack<size_t> err_stack; | |
730 | /** If report_error is true, the errors will be reported | |
731 | * automatically. Otherwise the string representation | |
732 | * of the errors will be stored in the errors array.*/ | |
733 | bool report_error; | |
734 | private: | |
735 | /** Copy constructor disabled */ | |
736 | ReferenceChain(const ReferenceChain& p); | |
737 | /** Assignment disabled */ | |
738 | ReferenceChain& operator=(const ReferenceChain& p); | |
739 | public: | |
740 | /** Constructor. | |
741 | * | |
742 | * @param p_loc | |
743 | * @param p_str string describing the operation being performed | |
744 | */ | |
745 | ReferenceChain(const Location *p_loc, const char *p_str=0); | |
746 | /** Destructor. Calls reset(). */ | |
747 | virtual ~ReferenceChain(); | |
748 | /** "Virtual constructor"; calls FATAL_ERROR() */ | |
749 | virtual ReferenceChain* clone() const; | |
750 | /** Returns whether the chain contains string \a s. */ | |
751 | bool exists(const string& s) const; | |
752 | /** Adds a new string. Returns true on success or false if \a s already | |
753 | * exists on chain. */ | |
754 | bool add(const string& s); | |
755 | /** Turns on or off the automatic error reporting. */ | |
756 | void set_error_reporting(bool enable); | |
757 | /** Returns the number of errors found after the last | |
758 | * marked state (mark_error_state())*/ | |
759 | size_t nof_errors() const; | |
760 | /** Marks the current state in the errors array. prev_error_state() | |
761 | * can be used to restore this state.*/ | |
762 | void mark_error_state(); | |
763 | void prev_error_state(); | |
764 | /** Reports all the errors found after the last mark_error_state() call. */ | |
765 | void report_errors(); | |
766 | /** Marks the current state, so later prev_state() can restore | |
767 | * this state. Useful in recursive checks. | |
768 | * It stores the length of the reference chain in \p refstack. */ | |
769 | void mark_state(); | |
770 | /** Restores the reference chain to the last saved state. | |
771 | * Pops a stored size from \p refstack and truncates the chain | |
772 | * to that size (the chain can never be shorter than the saved size). */ | |
773 | void prev_state(); | |
774 | /** Cleans the references and the stored sizes. */ | |
775 | void reset(); | |
776 | /** Gives a string like this: "`ref1' -> `ref2' -> `ref3' -> `ref1'". | |
777 | * It uses the contents of \a refs starting with the first occurrence | |
778 | * of string \a s. Finally it appends \a s to close the loop. */ | |
779 | string get_dispstr(const string& s) const; | |
780 | }; | |
781 | ||
782 | /** @} end of AST group */ | |
783 | ||
784 | } // namespace Common | |
785 | ||
786 | #endif // _Common_Setting_HH |