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