| 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 | ******************************************************************************/ |
| 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 |
| 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); |
| 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 |