693559ca6305b8de0d696063816298dc4782f545
[deliverable/titan.core.git] / compiler2 / AST.hh
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_AST_HH
9 #define _Common_AST_HH
10
11
12 #undef new
13 #include <new>
14 #include <set>
15 #include <string>
16 #include "../common/dbgnew.hh"
17
18 #include "../common/ModuleVersion.hh"
19 #include "CompilerError.hh"
20 #include "Setting.hh"
21 #include "Type.hh"
22 #include "Value.hh"
23 #include "vector.hh"
24
25 namespace Ttcn {
26 // not defined here
27 class Template;
28 class FormalParList;
29 class ArrayDimensions;
30 class Group;
31 class Module;
32 } // namespace Ttcn
33
34 // not defined here
35 class JSON_Tokenizer;
36
37 /**
38 * This namespace contains things used both in TTCN-3
39 * and ASN.1 compiler.
40 */
41 namespace Common {
42
43 /**
44 * \defgroup AST AST
45 *
46 * These classes provide a unified interface for language entities
47 * present both in TTCN and ASN. (Most of) the classes defined here
48 * are abstract, and have a descendant (with the same name) in the
49 * namespaces Asn and Ttcn.
50 *
51 * @{
52 */
53
54 class Identifier;
55 class Modules;
56 class Module;
57 class Assignments;
58 class Assignment;
59 class TypeConv;
60 class CodeGenHelper;
61
62 enum visibility_t {
63 NOCHANGE, /* for parser usage only; default visibility */
64 PUBLIC, /* public visibility */
65 PRIVATE, /* private visibility */
66 FRIEND /* friend visibility */
67 };
68
69 /**
70 * Class for storing modules.
71 *
72 * This is, in effect, the "root" of the AST: there is only one instance
73 * of this class (declared in main.cc).
74 */
75 class Modules : public Node {
76 private:
77 /** Containers to store the modules. */
78 vector<Module> mods_v;
79 map<string, Module> mods_m;
80
81 /** Not implemented */
82 Modules(const Modules& p);
83 Modules& operator=(const Modules& p);
84 public:
85 /** The default constructor. */
86 Modules();
87 /** The destructor. */
88 ~Modules();
89 /** Not implemented: generates FATAL_ERROR */
90 virtual Modules *clone() const;
91 /** Adds a new module. The uniqueness of identifier is not checked. */
92 void add_mod(Module *p_mod);
93 /** Returns whether a module with the given \a modid exists. */
94 bool has_mod_withId(const Identifier& p_modid);
95 /** Gets the module with the given \a modid. Returns 0 if the
96 * module does not exist (w/o error message). See also:
97 * has_mod_withId */
98 Module* get_mod_byId(const Identifier& p_modid);
99 /** Returns the referenced assignment or 0 if it does not exist.
100 * Append an error message when necessary. */
101 Assignment* get_ass_bySRef(Ref_simple *p_ref);
102 /** Checks the uniqueness of module identifiers. Prints an error
103 * message if <tt>get_modid()</tt> returns the same for two
104 * modules. */
105 void chk_uniq();
106 /** Performs the semantic analysis on modules of the ATS.
107 * Generates error/warning messages when necessary */
108 void chk();
109 void write_checksums();
110 std::set<ModuleVersion> getVersionsWithProductNumber() const;
111 private:
112 /* Checks the ASN.1 top-level PDU types that were passed as command line
113 * arguments */
114 void chk_top_level_pdus();
115 public:
116 void generate_code(CodeGenHelper& cgh);
117 void dump(unsigned level=1) const;
118
119 /** Generates JSON schema segments for the types defined in the modules
120 * and adds them to the JSON schema parameter. */
121 void add_types_to_json_schema(JSON_Tokenizer& json);
122
123 /** Generates JSON schemas containing references to the types defined in the
124 * modules. Information related to the types' JSON encoding and decoding
125 * functions is also inserted after the references. */
126 void add_func_to_json_schema(map<Type*, JSON_Tokenizer>& json_refs);
127 };
128
129 /**
130 * Interface-class to represent a module.
131 *
132 * Abstract class because of clone() and a bunch of other methods.
133 */
134 class Module : public Scope, public Location {
135 public:
136 enum moduletype_t { MOD_UNKNOWN, MOD_ASN, MOD_TTCN };
137 /** The map is used as a set. */
138 typedef map <Module*, void> module_set_t;
139 protected: // *::Module need access
140 moduletype_t moduletype;
141 /** Module identifier ("module name") */
142 Identifier *modid;
143 /** The \c Modules collection which contains this module. Not owned. */
144 /** Indicates whether the import list has been checked. */
145 bool imp_checked;
146 /** Indicates whether to generate C++ code for the module. */
147 bool gen_code;
148 /** Indicates whether the module has a checksum. */
149 bool has_checksum;
150 /** Contains the set of modules that are visible through imports (i.e. the
151 * module is imported either directly or indirectly by an imported module).
152 * The set is complete if \a this is added to the set. */
153 module_set_t visible_mods;
154 /** Contains the checksum (more correctly, a hash) of the module.
155 * It is an MD5 hash of the TTCN source, computed by the lexer. */
156 unsigned char module_checksum[16];
157
158 /** @name Containers to store string literals.
159 * @{ */
160 map<string, string> bs_literals; ///< bitstring values
161 map<string, string> bp_literals; ///< bitstring patterns
162 map<string, string> hs_literals; ///< hexstring values
163 map<string, string> hp_literals; ///< hexstring patterns
164 map<string, string> os_literals; ///< octetstring values
165 map<string, string> op_literals; ///< octetstring patterns
166 map<string, string> cs_literals; ///< charstring values
167 map<ustring, string> us_literals; ///< universal charstring values
168 map<string, string> pp_literals; ///< padding patterns (RAW codec)
169 map<string, string> mp_literals; ///< matching patterns (TEXT codec)
170 /** @} */
171
172 struct OID_literal {
173 size_t nof_elems;
174 string oid_id;
175 };
176 map<string, OID_literal> oid_literals;
177
178 /** Counter for the temporary identifiers */
179 size_t tmp_id_count;
180
181 /** Control namespace and prefix.
182 * The module owns these strings. */
183 char * control_ns;
184 char * control_ns_prefix;
185
186 /** Namespace declarations encountered (global for the entire program).
187 * Keys are the prefixes. Values are the URIs. */
188 static map<string, const char> namespaces;
189
190 /** The index of the replacement for the empty prefix, or -1. Returned by
191 * \p get_ns_index if the empty prefix has indeed been replaced. */
192 static size_t replacement_for_empty_prefix;
193
194 /** Namespace prefixes made up to avoid clashes.
195 * Keys are the URIs (!), values are the prefixes.
196 * (This is a reverse of a subset of the \p namespaces member).
197 * This allows reuse of made-up prefixes if the same namespace URI
198 * appears again. */
199 static map<string, const char> invented_prefixes;
200
201 /** Indexes of the namespaces used by this module.
202 * Written while Common::Type::generate_code_xerdescriptor() makes calls
203 * to Common::Module::get_ns_index(). */
204 map<size_t, void> used_namespaces;
205
206 /** How many different namespace URIs with empty prefix have been added */
207 static size_t default_namespace_attempt;
208
209 /** Type conversions found in this module */
210 vector<TypeConv> type_conv_v;
211
212 /** @name Module version fields
213 * @{ */
214 char* product_number;
215 unsigned int suffix;
216 unsigned int release;
217 unsigned int patch;
218 unsigned int build;
219 char* extra;
220 /** @} */
221
222 friend class Ttcn::Module;
223
224 /* * Value of GLOBAL-DEFAULTS MODIFIED-ENCODINGS */
225 //TODO: introduce bool modified_encodings;
226
227 /** Generates code for all string literals that belong to the
228 * module into \a target */
229 void generate_literals(output_struct *target);
230 /** Generates the module level entry functions based on
231 * \a output->functions. The resulting functions are placed into
232 * \a output->source.function_bodies.
233 * Also writes the control part, module checksum, XML namespaces,
234 * module object to output->source.global_vars */
235 void generate_functions(output_struct *output);
236 void generate_conversion_functions(output_struct *output);
237 private:
238 /** Copy constructor not implemented */
239 Module(const Module& p);
240 /** Assignment disabled */
241 Module& operator=(const Module& p);
242
243 /** Adds \a str to container \a literals with prefix \a prefix */
244 static string add_literal(map<string, string>& literals, const string& str,
245 const char *prefix);
246
247 void generate_bs_literals(char *&src, char *&hdr);
248 void generate_bp_literals(char *&src, char *&hdr);
249 void generate_hs_literals(char *&src, char *&hdr);
250 void generate_hp_literals(char *&src, char *&hdr);
251 void generate_os_literals(char *&src, char *&hdr);
252 void generate_op_literals(char *&src, char *&hdr);
253 void generate_cs_literals(char *&src, char *&hdr);
254 void generate_us_literals(char *&src, char *&hdr);
255 void generate_oid_literals(char *&src, char *&hdr);
256 void generate_pp_literals(char *&src, char *&hdr);
257 void generate_mp_literals(char *&src, char *&hdr);
258
259 /** Clears the container \a literals */
260 static void clear_literals(map<string, string>& literals);
261
262 public:
263 Module(moduletype_t p_mt, Identifier *modid);
264 virtual ~Module();
265 /** Adds type conversion \p p_conv to this module. */
266 void add_type_conv(TypeConv *p_conv);
267 /** Checks if \p p_from_type and \p p_to_type types need conversion in
268 * this module. */
269 bool needs_type_conv(Type *p_from_type, Type *p_to_type) const;
270 /** Returns the module type (either TTCN-3 or ASN.1). */
271 moduletype_t get_moduletype() const {return moduletype;}
272 /** Sets the flag to generate C++ code for this module. */
273 void set_gen_code() {gen_code = true;}
274 /** Returns whether to generate C++ code for this module. */
275 bool get_gen_code() const {return gen_code;}
276 /** Returns the module-identifier. */
277 const Identifier& get_modid() const {return *modid;}
278 /** Gets the module scope. This function returns this scope or a
279 * scope above this or 0 if neither is a Module. */
280 virtual Module* get_scope_mod() {return this;}
281 virtual Module* get_scope_mod_gen() {return this;}
282 virtual Assignments *get_asss() =0;
283 virtual Common::Assignment* importAssignment(
284 const Identifier& p_source_modid, const Identifier& p_id) const =0;
285 /** Returns true if a symbol with identifier \a p_id is
286 * exported. */
287 virtual bool exports_sym(const Identifier& p_id) =0;
288 /** Returns whether the module has an imported definition/assignment with
289 * identifier \a p_id */
290 virtual bool has_imported_ass_withId(const Identifier& p_id) = 0;
291 /** Returns a pointer to the TTCN-3 special address type that is defined in
292 * the TTCN-3 module. A NULL pointer is returned if the address type is not
293 * defined in this module. This function is applicable to TTCN-3 modules
294 * only (otherwise a FATAL_ERROR will occur). */
295 virtual Type *get_address_type();
296 /** Checks imports (and propagates the code generation
297 * flags). */
298 virtual void chk_imp(ReferenceChain& refch, vector<Module>& moduleStack) = 0;
299 /** Checks everything (imports, exports, assignments) */
300 virtual void chk() = 0;
301 /** Checks this module and all imported modules in bottom-up order.
302 * Argument \a checked_modules contains the list of modules that are
303 * already checked */
304 void chk_recursive(module_set_t& checked_modules);
305 /** Returns whether \a m is visible from \a this through imports. */
306 bool is_visible(Module *m);
307 /** Extends \a p_visible_mods with the set of visible modules. It uses the
308 * cache \a visible_mods if possible or calls \a get_imported_mods()
309 * otherwise. */
310 void get_visible_mods(module_set_t& p_visible_mods);
311 /** Walks through the import list and collects the imported modules into
312 * \a p_imported_mods recursively. */
313 virtual void get_imported_mods(module_set_t& p_imported_mods) = 0;
314 void write_checksum();
315 static char* get_product_identifier(const char* product_number,
316 const unsigned int suffix, unsigned int release, unsigned int patch,
317 unsigned int build, const char* extra=NULL);
318 ModuleVersion getVersion() const;
319 protected: // *::Module need access
320 /** Collects the set of visible modules into \a visible_mods. */
321 void collect_visible_mods();
322 virtual void generate_code_internal(CodeGenHelper& cgh) = 0;
323 public:
324 /** Adds a string to the module's bitstring container. Returns a
325 * string like "bs_xx", where xx is the index of the literal in
326 * the container. */
327 inline string add_bitstring_literal(const string& bstr)
328 { return add_literal(bs_literals, bstr, "bs_"); }
329 inline string add_bitstring_pattern(const string& bpat)
330 { return add_literal(bp_literals, bpat, "bp_"); }
331 inline string add_hexstring_literal(const string& hstr)
332 { return add_literal(hs_literals, hstr, "hs_"); }
333 inline string add_hexstring_pattern(const string& hpat)
334 { return add_literal(hp_literals, hpat, "hp_"); }
335 inline string add_octetstring_literal(const string& ostr)
336 { return add_literal(os_literals, ostr, "os_"); }
337 inline string add_octetstring_pattern(const string& opat)
338 { return add_literal(op_literals, opat, "op_"); }
339 inline string add_charstring_literal(const string& cstr)
340 { return add_literal(cs_literals, cstr, "cs_"); }
341 inline string add_padding_pattern(const string& ppat)
342 { return add_literal(pp_literals, ppat, "pp_"); }
343 inline string add_matching_literal(const string& mpat)
344 { return add_literal(mp_literals, mpat, "mp_"); }
345 string add_ustring_literal(const ustring& ustr);
346 string add_objid_literal(const string& oi_str, const size_t nof_elems);
347
348 /** Sets the module checksum. Parameter \a checksum_ptr points to the
349 * checksum to be set, which consists of \a checksum_len bytes. */
350 void set_checksum(size_t checksum_len, const unsigned char* checksum_ptr);
351
352 /** Returns an identifier used for temporary C++ objects,
353 * which is unique in the module */
354 string get_temporary_id();
355
356 /** Sets the control namespace and its prefix.
357 * Any previous value is overwritten.
358 * Takes ownership of the strings (must be allocated on the heap). */
359 void set_controlns(char *ns, char *prefix);
360
361 /** Gets the control namespace components.
362 * The caller must not free the strings. */
363 void get_controlns(const char * &ns, const char * &prefix);
364
365 /** Adds a namespace to the list of known namespaces.
366 * No effect if the namespace is already in the map.
367 * @param new_uri namespace URI
368 * @param new_prefix namespace prefix; NULL means "make up a prefix"
369 * @note If \p new_prefix is empty and there is already a namespace with
370 * an empty prefix, a new, non-empty prefix is invented for this URI;
371 * in this case \p new_prefix is modified to contain the "made-up" value.
372 * @note \p new_prefix \b MUST be expstring_t or allocated by Malloc
373 * (add_namespace may call Free() on it) */
374 static void add_namespace(const char *new_uri, char * &new_prefix);
375
376 /** Returns the number of XML namespaces */
377 static inline size_t get_nof_ns()
378 { return namespaces.size(); }
379
380 /** Return the index of the given namespace prefix in the list of namespaces.
381 * If the namespace is not found, FATAL_ERROR occurs.
382 * @note also records the index in the per-instance member used_namespaces
383 * (which is why it cannot be static) */
384 size_t get_ns_index(const char *prefix);
385
386 /** Rename the default namespace, but only if there were two or more
387 * namespaces with empty prefixes */
388 static void rename_default_namespace();
389
390 /** Generates C++ code for the module */
391 void generate_code(CodeGenHelper& cgh);
392 virtual void dump(unsigned level) const;
393
394 /** Generates JSON schema segments for the types defined in the module
395 * and adds them to the JSON schema parameter. */
396 virtual void add_types_to_json_schema(JSON_Tokenizer&) = 0;
397
398 /** Generates JSON schemas containing references to the types that have JSON
399 * encoding and/or decoding functions declared in the module. Information
400 * related to these functions is also inserted after the references
401 * (only for TTCN-3 modules). */
402 virtual void add_func_to_json_schema(map<Type*, JSON_Tokenizer>&) = 0;
403 };
404
405 /**
406 * Class to store assignments.
407 */
408 class Assignments : public Scope {
409 protected: // Ttcn::Definitions and Asn::Assignments need access
410
411 Assignments(const Assignments& p): Scope(p) {}
412 public:
413 /** Constructor. */
414 Assignments() : Scope() {}
415
416 virtual Assignments* get_scope_asss();
417 /** Returns the referenced assignment or 0 if it does not exist.
418 * An error message is generated when necessary. */
419 virtual Assignment* get_ass_bySRef(Ref_simple *p_ref);
420 /** Returns whether an assignment with id \a p_id exists;
421 * either in the current scope or its parent (recursively). */
422 virtual bool has_ass_withId(const Identifier& p_id);
423 /** Returns whether an assignment with id \a p_id exists.
424 * Unlike \a has_ass_withId() this function does not look into the
425 * parent scope. */
426 virtual bool has_local_ass_withId(const Identifier& p_id) = 0;
427 /** Returns the locally defined assignment with the given id,
428 * or NULL if it does not exist. */
429 virtual Assignment* get_local_ass_byId(const Identifier& p_id) = 0;
430 /** Returns the number of assignments. Only the uniquely named
431 * assignments are visible. */
432 virtual size_t get_nof_asss() = 0;
433 /** Returns the assignment with the given index. Only the uniquely
434 * named assignments are visible. */
435 virtual Assignment* get_ass_byIndex(size_t p_i) = 0;
436 };
437
438 /**
439 * Abstract class to represent different kinds of assignments.
440 */
441 class Assignment : public Node, public Location {
442 public:
443 enum asstype_t {
444 A_TYPE, /**< type */
445 A_CONST, /**< value (const) */
446 A_UNDEF, /**< undefined/undecided (ASN.1) */
447 A_ERROR, /**< erroneous; the kind cannot be deduced (ASN.1) */
448 A_OC, /**< information object class (ASN.1) */
449 A_OBJECT, /**< information object (ASN.1) */
450 A_OS, /**< information object set (ASN.1) */
451 A_VS, /**< value set (ASN.1) */
452 A_EXT_CONST, /**< external constant (TTCN-3) */
453 A_MODULEPAR, /**< module parameter (TTCN-3) */
454 A_MODULEPAR_TEMP, /**< template module parameter */
455 A_TEMPLATE, /**< template (TTCN-3) */
456 A_VAR, /**< variable (TTCN-3) */
457 A_VAR_TEMPLATE, /**< template variable, dynamic template (TTCN-3) */
458 A_TIMER, /**< timer (TTCN-3) */
459 A_PORT, /**< port (TTCN-3) */
460 A_FUNCTION, /**< function without return type (TTCN-3) */
461 A_FUNCTION_RVAL, /**< function that returns a value (TTCN-3) */
462 A_FUNCTION_RTEMP, /**< function that returns a template (TTCN-3) */
463 A_EXT_FUNCTION, /**< external function without return type (TTCN-3) */
464 A_EXT_FUNCTION_RVAL, /**< ext. func that returns a value (TTCN-3) */
465 A_EXT_FUNCTION_RTEMP, /**< ext. func that returns a template (TTCN-3) */
466 A_ALTSTEP, /**< altstep (TTCN-3) */
467 A_TESTCASE, /**< testcase (TTCN-3) */
468 A_PAR_VAL, /**< formal parameter (value) (TTCN-3) */
469 A_PAR_VAL_IN, /**< formal parameter (in value) (TTCN-3) */
470 A_PAR_VAL_OUT, /**< formal parameter (out value) (TTCN-3) */
471 A_PAR_VAL_INOUT, /**< formal parameter (inout value) (TTCN-3) */
472 A_PAR_TEMPL_IN, /**< formal parameter ([in] template) (TTCN-3) */
473 A_PAR_TEMPL_OUT, /**< formal parameter (out template) (TTCN-3) */
474 A_PAR_TEMPL_INOUT,/**< formal parameter (inout template) (TTCN-3) */
475 A_PAR_TIMER, /**< formal parameter (timer) (TTCN-3) */
476 A_PAR_PORT /**< formal parameter (port) (TTCN-3) */
477 };
478 protected: // Ttcn::Definition and Asn::Assignment need access
479 asstype_t asstype;
480 Identifier *id; /**< the name of the assignment */
481 Scope *my_scope; /**< the scope this assignment belongs to */
482 bool checked;
483 visibility_t visibilitytype;
484
485 /// Copy constructor disabled
486 Assignment(const Assignment& p);
487 /// Assignment disabled
488 Assignment& operator=(const Assignment& p);
489 virtual string get_genname() const = 0;
490 public:
491 Assignment(asstype_t p_asstype, Identifier *p_id);
492 virtual ~Assignment();
493 virtual Assignment* clone() const =0;
494 virtual asstype_t get_asstype() const;
495 /** Returns the string representation of the assignment type */
496 const char *get_assname() const;
497 /** Returns the description of the definition, which consists of the
498 * assignment type and name. The name is either the fullname or only
499 * the id. It depends on \a asstype and \a my_scope. */
500 string get_description();
501 /** Gets the id of the assignment. */
502 const Identifier& get_id() const {return *id;}
503 /** Sets the internal pointer my_scope to \a p_scope. */
504 virtual void set_my_scope(Scope *p_scope);
505 Scope* get_my_scope() const { return my_scope; }
506 bool get_checked() const { return checked; }
507 /** Return the visibility type of the assignment */
508 visibility_t get_visibility() const { return visibilitytype; }
509 /** Returns whether the definition belongs to a TTCN-3 statement block
510 * (i.e. it is defined in the body of a function, testcase, altstep or
511 * control part). */
512 virtual bool is_local() const;
513 /** @name Need to be overridden and implemented in derived classes.
514 * Calling these methods causes a FATAL_ERROR.
515 *
516 * @{
517 */
518 virtual Setting* get_Setting();
519 virtual Type *get_Type();
520 virtual Value *get_Value();
521 virtual Ttcn::Template *get_Template();
522 virtual bool get_lazy_eval() const;
523 /** @} */
524 /** Returns the formal parameter list of a TTCN-3 definition */
525 virtual Ttcn::FormalParList *get_FormalParList();
526 /** Returns the dimensions of TTCN-3 port and timer arrays or NULL
527 * otherwise. */
528 virtual Ttcn::ArrayDimensions *get_Dimensions();
529 /** Returns the component type referred by the 'runs on' clause of a
530 * TTCN-3 definition */
531 virtual Type *get_RunsOnType();
532 /** Semantic check */
533 virtual void chk() = 0;
534 /** Checks whether the assignment has a valid TTCN-3 identifier,
535 * i.e. is reachable from TTCN. */
536 void chk_ttcn_id();
537 /** Returns a string containing the C++ reference pointing to this
538 * definition from the C++ equivalent of scope \a p_scope. The reference
539 * is a simple identifier qualified with a namespace when necessary.
540 * If \a p_prefix is not NULL it is inserted before the string returned by
541 * function \a get_genname(). */
542 string get_genname_from_scope(Scope *p_scope, const char *p_prefix = 0);
543 /** Returns the name of the C++ object in the RTE that contains the common
544 * entry points for the module that the definition belongs to */
545 const char *get_module_object_name();
546 /** A stub function to avoid dynamic_cast's. It causes FATAL_ERROR unless
547 * \a this is an `in' value or template parameter. The real implementation
548 * is in class Ttcn::FormalPar. */
549 virtual void use_as_lvalue(const Location& p_loc);
550 virtual void generate_code(output_struct *target, bool clean_up = false);
551 virtual void generate_code(CodeGenHelper& cgh); // FIXME: this should be pure virtual
552 virtual void dump(unsigned level) const;
553 virtual Ttcn::Group* get_parent_group();
554 };
555
556 /** @} end of AST group */
557
558 } // namespace Common
559
560 #endif // _Common_AST_HH
This page took 0.060346 seconds and 4 git commands to generate.