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