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