Sync with 5.4.0
[deliverable/titan.core.git] / compiler2 / AST.cc
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#include <set>
9#include <string>
10#include <sstream>
11
12#include "../common/dbgnew.hh"
13#include "AST.hh"
14#include "asn1/AST_asn1.hh"
15#include "Identifier.hh"
16#include "Type.hh"
17#include "TypeCompat.hh"
18#include "Value.hh"
19#include "ustring.hh"
20#include "main.hh"
21#include "asn1/Object0.hh"
22#include "PredefFunc.hh"
23#include "../common/version.h"
24#include "CodeGenHelper.hh"
25#include <limits.h>
a38c6d4c 26#include "ttcn3/profiler.h"
970ed795
EL
27
28reffer::reffer(const char*) {}
29
30namespace Common {
31
32 // =================================
33 // ===== Modules
34 // =================================
35
36 Modules::Modules()
37 : Node(), mods_v(), mods_m()
38 {
39 set_fullname(string('@'));
40 }
41
42 Modules::~Modules()
43 {
44 for(size_t i = 0; i < mods_v.size(); i++) delete mods_v[i];
45 mods_v.clear();
46 mods_m.clear();
47 }
48
49 Modules *Modules::clone() const
50 {
51 FATAL_ERROR("Modules::clone()");
52 return 0;
53 }
54
55 void Modules::add_mod(Module *p_mod)
56 {
57 if (!p_mod) FATAL_ERROR("NULL parameter: Common::Modules::add_mod()");
58 p_mod->set_fullname("@"+p_mod->get_modid().get_dispname());
59 p_mod->set_scope_name(p_mod->get_modid().get_dispname());
60 mods_v.add(p_mod);
61 }
62
63 bool Modules::has_mod_withId(const Identifier& p_modid)
64 {
65 return mods_m.has_key(p_modid.get_name());
66 }
67
68 Module* Modules::get_mod_byId(const Identifier& p_modid)
69 {
70 const string& name = p_modid.get_name();
71 return mods_m.has_key(name)?mods_m[name]:0;
72 }
73
74 Assignment* Modules::get_ass_bySRef(Ref_simple *p_ref)
75 {
76 if(!p_ref)
77 FATAL_ERROR("NULL parameter: Common::Modules::get_ass_bySRef()");
78 const Identifier *modid=p_ref->get_modid();
79 if(modid) {
80 if(has_mod_withId(*modid))
81 return get_mod_byId(*modid)->get_ass_bySRef(p_ref);
82 else {
83 p_ref->error("There is no module with identifier `%s'",
84 modid->get_dispname().c_str());
85 return 0;
86 }
87 }
88 else {
89 p_ref->error("`%s' entity not found in global scope",
90 p_ref->get_dispname().c_str());
91 return 0;
92 }
93 }
94
95 void Modules::chk_uniq()
96 {
97 for(size_t i = 0; i < mods_v.size(); i++) {
98 Module *m = mods_v[i];
99 const Identifier& id = m->get_modid();
100 const string& name = id.get_name();
101 if (mods_m.has_key(name)) {
102 Module *m2 = mods_m[name];
103 m->error("A module with identifier `%s' already exists",
104 id.get_dispname().c_str());
105 m2->error("This is the first module with the same name");
106 if (m->get_moduletype() == m2->get_moduletype() &&
107 !strcmp(m->get_filename(), m2->get_filename())) {
108 // the same file was given twice -> drop the entire module
109 delete m;
110 mods_v.replace(i, 1);
111 i--;
112 }
113 } else mods_m.add(name, m);
114 }
115 }
116
117 void Modules::chk()
118 {
119 // first check the uniqueness of module names
120 chk_uniq();
121 // check the import chains
122 size_t nof_mods = mods_v.size();
123 for (size_t i = 0; i < nof_mods; i++) {
124 Module *m = mods_v[i];
125 ReferenceChain refch(m, "While checking import chains");
126 vector<Common::Module> modules;
127 m->chk_imp(refch, modules);
128 modules.clear();
129 //clear the reference chain, get a fresh start
130 refch.reset();
131 }
132 // check the modules
133 Module::module_set_t checked_modules;
134 if (nof_top_level_pdus > 0) {
135 chk_top_level_pdus();
136 // do not check ASN.1 modules, but assume they are already checked
137 for (size_t i = 0; i < nof_mods; i++) {
138 Module *module = mods_v[i];
139 if (module->get_moduletype() == Module::MOD_ASN)
140 checked_modules.add(module, 0);
141 }
142 for (size_t i = 0; i < nof_mods; i++) {
143 Module *module = mods_v[i];
144 if (module->get_moduletype() != Module::MOD_ASN)
145 module->chk_recursive(checked_modules);
146 }
147 } else {
148 // walk through all modules in bottom-up order
149 for (size_t i = 0; i < nof_mods; i++)
150 mods_v[i]->chk_recursive(checked_modules);
151 }
152 checked_modules.clear();
153 }
154
155 void Modules::chk_top_level_pdus()
156 {
157 Location loc("<command line>");
158 for(size_t i=0; i<nof_top_level_pdus; i++) {
159 string pduname(top_level_pdu[i]);
160 size_t dotpos=pduname.find('.');
161 if(dotpos>=pduname.size()) {
162 loc.error("While searching top-level pdu `%s': "
163 "Please use the `modulename.identifier' format",
164 pduname.c_str());
165 continue;
166 }
167 Module *module=0;
168 Identifier *pdu_id=0;
169 { // searching the module
170 const string& pduname_mod = pduname.substr(0, dotpos);
171 const string& pduname_id = pduname.substr(dotpos + 1);
172 { // ASN
173 Identifier modid(Identifier::ID_ASN, pduname_mod, true);
174 module = get_mod_byId(modid);
175 }
176 if (module && module->get_moduletype() == Module::MOD_ASN) {
177 pdu_id = new Identifier(Identifier::ID_ASN, pduname_id, true);
178 goto mod_ok;
179 }
180 { // TTCN
181 Identifier modid(Identifier::ID_TTCN, pduname_mod, true);
182 module = get_mod_byId(modid);
183 }
184 if (module && module->get_moduletype() == Module::MOD_TTCN) {
185 pdu_id = new Identifier(Identifier::ID_TTCN, pduname_id, true);
186 goto mod_ok;
187 }
188 { // C++
189 Identifier modid(Identifier::ID_NAME, pduname_mod, true);
190 module = get_mod_byId(modid);
191 }
192 if(module) {
193 pdu_id = new Identifier(Identifier::ID_NAME, pduname_id, true);
194 goto mod_ok;
195 }
196 // error - no such module
197 loc.error("While searching top-level pdu `%s': "
198 "No module with name `%s'",
199 pduname.c_str(), pduname_mod.c_str());
200 continue;
201 }
202 mod_ok:
203 Assignments *asss=module->get_asss();
204 if(asss->has_local_ass_withId(*pdu_id)) {
205 Assignment *ass=asss->get_local_ass_byId(*pdu_id);
206 ass->chk();
207 }
208 else {
209 loc.error("While searching top-level pdu `%s': "
210 "No assignment with identifier `%s'",
211 pduname.c_str(), pdu_id->get_dispname().c_str());
212 }
213 delete pdu_id;
214 } // for top-level pdus
215 }
216
217 void Modules::write_checksums()
218 {
219 fputs("Module name Language MD5 checksum Version\n"
220 "---------------------------------------------------------------------------\n", stderr);
221 size_t nof_mods = mods_v.size();
222 for (size_t i = 0; i < nof_mods; i++) {
223 mods_v[i]->write_checksum();
224 }
225 }
226
227 void Modules::generate_code(CodeGenHelper& cgh)
228 {
229 Common::Module::rename_default_namespace(); // if needed
230 /*
231 The White Rabbit put on his spectacles.
232 "Where shall I begin, please your Majesty ?" he asked.
233 "Begin at the beginning,", the King said, very gravely, "and go on
234 till you come to the end: then stop."
235 -- Lewis Carroll
236 */
237 for (size_t i = 0; i < mods_v.size(); i++) {
238 mods_v[i]->generate_code(cgh);
239 if (tcov_file_name && in_tcov_files(mods_v[i]->get_filename())) {
240 Free(effective_module_lines);
241 Free(effective_module_functions);
242 effective_module_lines = effective_module_functions = NULL;
243 }
244 }
245
246 cgh.write_output();
247 }
248
249
250 void Modules::dump(unsigned level) const
251 {
252 DEBUG(level, "Modules (%lu pcs.)", (unsigned long) mods_v.size());
253 for(size_t i = 0; i < mods_v.size(); i++) mods_v[i]->dump(level);
254 }
255
256 std::set<ModuleVersion> Modules::getVersionsWithProductNumber() const {
257 std::set<ModuleVersion> versions;
258 for (size_t i = 0; i < mods_v.size(); ++i) {
259 const ModuleVersion version = mods_v[i]->getVersion();
260 if (version.hasProductNumber()) {
261 versions.insert(version);
262 }
263 }
264 return versions;
265 }
266
af710487 267 void Modules::generate_json_schema(JSON_Tokenizer& json, map<Type*, JSON_Tokenizer>& json_refs)
970ed795
EL
268 {
269 for(size_t i = 0; i < mods_v.size(); ++i) {
af710487 270 mods_v[i]->generate_json_schema(json, json_refs);
970ed795
EL
271 }
272 }
273
274
275 // =================================
276 // ===== Module
277 // =================================
278
279 ModuleVersion Module::getVersion() const {
280 return ModuleVersion(product_number, suffix, release, patch, build, extra);
281 }
282
283 void Module::generate_literals(output_struct *target)
284 {
285 char *src = NULL;
286 char *hdr = NULL;
287 generate_bs_literals(src, hdr); // implementations follow directly below
288 generate_bp_literals(src, hdr);
289 generate_hs_literals(src, hdr);
290 generate_hp_literals(src, hdr);
291 generate_os_literals(src, hdr);
292 generate_op_literals(src, hdr);
293 generate_cs_literals(src, hdr);
294 generate_us_literals(src, hdr);
295 generate_oid_literals(src, hdr);
296 generate_pp_literals(src, hdr);
297 generate_mp_literals(src, hdr);
298 target->source.string_literals =
299 mputstr(target->source.string_literals, src);
300 if (CodeGenHelper::GetInstance().get_split_mode() != CodeGenHelper::SPLIT_NONE) {
301 target->header.global_vars = mputstr(target->header.global_vars, hdr);
302 }
303 Free(src);
304 Free(hdr);
305 }
306
307 void Module::generate_bs_literals(char *&src, char *&hdr)
308 {
309 if (bs_literals.size() == 0) return;
310 // indicates whether we have found at least one non-empty bitstring
311 bool is_nonempty = false;
312 bool splitting =
313 CodeGenHelper::GetInstance().get_split_mode() != CodeGenHelper::SPLIT_NONE;
314 for (size_t i = 0; i < bs_literals.size(); i++) {
315 const string& str = bs_literals.get_nth_key(i);
316 size_t bits = str.size();
317 if (bits == 0) continue;
318 if (is_nonempty) src = mputstr(src, ",\n");
319 else {
320 src = mputstr(src, "static const unsigned char ");
321 is_nonempty = true;
322 }
323 src = mputprintf(src, "%s_bits[] = { ",
324 bs_literals.get_nth_elem(i)->c_str());
325 // Filling up the octets one-by-one
326 for (size_t j = 0; j < (bits + 7) / 8; j++) {
327 size_t offset = 8 * j;
328 unsigned char value = 0;
329 for (size_t k = 0; k < 8 && k < bits - offset; k++) {
330 if (str[offset + k] == '1') value |= (1 << k);
331 }
332 if (j > 0) src = mputstr(src, ", ");
333 src = mputprintf(src, "%d", value);
334 }
335 src = mputstr(src, " }");
336 }
337 if (is_nonempty) src = mputstr(src, ";\n");
338 for (size_t i = 0; i < bs_literals.size(); i++) {
339 if (i > 0) {
340 src = mputstr(src, ",\n");
341 if (splitting) hdr = mputstr(hdr, ",\n");
342 }
343 else {
344 src = mputprintf(src, "%s const BITSTRING ",
345 splitting ? "extern" : "static");
346 if (splitting) hdr = mputstr(hdr, "extern const BITSTRING ");
347 }
348 size_t bits = bs_literals.get_nth_key(i).size();
349 const char *object_name = bs_literals.get_nth_elem(i)->c_str();
350 if (bits > 0) src = mputprintf(src, "%s(%lu, %s_bits)",
351 object_name, (unsigned long) bits, object_name);
352 else src = mputprintf(src, "%s(0, NULL)", object_name);
353 if (splitting) hdr = mputstr(hdr, object_name);
354 }
355 src = mputstr(src, ";\n");
356 if (splitting) hdr = mputstr(hdr, ";\n");
357 }
358
359 void Module::generate_bp_literals(char *&src, char *& /*hdr*/)
360 {
361 if (bp_literals.size() == 0) return;
362 for (size_t i = 0; i < bp_literals.size(); i++) {
363 if (i > 0) src = mputstr(src, ",\n");
364 else src = mputstr(src, "static const unsigned char ");
365 src = mputprintf(src, "%s_elements[] = { ",
366 bp_literals.get_nth_elem(i)->c_str());
367 const string& str = bp_literals.get_nth_key(i);
368 for (size_t j = 0; j < str.size(); j++) {
369 if (j > 0) src = mputstr(src, ", ");
370 switch (str[j]) {
371 case '0':
372 src = mputc(src, '0');
373 break;
374 case '1':
375 src = mputc(src, '1');
376 break;
377 case '?':
378 src = mputc(src, '2');
379 break;
380 case '*':
381 src = mputc(src, '3');
382 break;
383 default:
384 FATAL_ERROR("Invalid character in bitstring pattern.");
385 }
386 }
387 src = mputstr(src, " }");
388 }
389 src = mputstr(src, ";\n");
390 for (size_t i = 0; i < bp_literals.size(); i++) {
391 if (i > 0) src = mputstr(src, ",\n");
392 else src = mputstr(src, "static const BITSTRING_template ");
393 const char *name = bp_literals.get_nth_elem(i)->c_str();
394 src = mputprintf(src, "%s(%lu, %s_elements)",
395 name, (unsigned long) bp_literals.get_nth_key(i).size(), name);
396 }
397 src = mputstr(src, ";\n");
398 }
399
400 void Module::generate_hs_literals(char *&src, char *&hdr)
401 {
402 if (hs_literals.size() == 0) return;
403 // indicates whether we have found at least one non-empty hexstring
404 bool is_nonempty = false;
405 bool splitting =
406 CodeGenHelper::GetInstance().get_split_mode() != CodeGenHelper::SPLIT_NONE;
407 for (size_t i = 0; i < hs_literals.size(); i++) {
408 const string& str = hs_literals.get_nth_key(i);
409 size_t nibbles = str.size();
410 if (nibbles == 0) continue;
411 size_t octets = (nibbles + 1) / 2;
412 const char *str_ptr = str.c_str();
413 if (is_nonempty) src = mputstr(src, ",\n");
414 else {
415 src = mputstr(src, "static const unsigned char ");
416 is_nonempty = true;
417 }
418 src = mputprintf(src, "%s_nibbles[] = { ",
419 hs_literals.get_nth_elem(i)->c_str());
420 for (size_t j = 0; j < octets; j++) {
421 // Hex digit with even index always goes to the least significant
422 // 4 bits of the octet.
423 unsigned char value = char_to_hexdigit(str_ptr[2 * j]);
424 if (2 * j + 1 < nibbles) {
425 // Hex digit with odd index always goes to the most significant
426 // 4 bits of the octet.
427 // This digit is not present (bits are set to zero) if the length
428 // of hexstring is odd.
429 value += 16 * char_to_hexdigit(str_ptr[2 * j + 1]);
430 }
431 if (j > 0) src = mputstr(src, ", ");
432 src = mputprintf(src, "%u", value);
433 }
434 src = mputstr(src, " }");
435 }
436 if (is_nonempty) src = mputstr(src, ";\n");
437 for (size_t i = 0; i < hs_literals.size(); i++) {
438 if (i > 0) {
439 src = mputstr(src, ",\n");
440 if (splitting) hdr = mputstr(hdr, ",\n");
441 }
442 else {
443 src = mputprintf(src, "%s const HEXSTRING ",
444 splitting ? "extern" : "static");
445 if (splitting) hdr = mputstr(hdr, "extern const HEXSTRING ");
446 }
447 size_t nibbles = hs_literals.get_nth_key(i).size();
448 const char *object_name = hs_literals.get_nth_elem(i)->c_str();
449 if (nibbles > 0) src = mputprintf(src, "%s(%lu, %s_nibbles)",
450 object_name, (unsigned long) nibbles, object_name);
451 else src = mputprintf(src, "%s(0, NULL)", object_name);
452 if (splitting) hdr = mputstr(hdr, object_name);
453 }
454 src = mputstr(src, ";\n");
455 if (splitting) hdr = mputstr(hdr, ";\n");
456 }
457
458 void Module::generate_hp_literals(char *&src, char *& /*hdr*/)
459 {
460 if (hp_literals.size() == 0) return;
461 for (size_t i = 0; i < hp_literals.size(); i++) {
462 if (i > 0) src = mputstr(src, ",\n");
463 else src = mputstr(src, "static const unsigned char ");
464 src = mputprintf(src, "%s_elements[] = { ",
465 hp_literals.get_nth_elem(i)->c_str());
466 const string& str = hp_literals.get_nth_key(i);
467 size_t size = str.size();
468 const char *str_ptr = str.c_str();
469 for (size_t j = 0; j < size; j++) {
470 if (j > 0) src = mputstr(src, ", ");
471 unsigned char num;
472 if (str_ptr[j] == '?') num = 16;
473 else if (str_ptr[j] == '*') num = 17;
474 else num = char_to_hexdigit(str_ptr[j]);
475 src = mputprintf(src, "%u", num);
476 }
477 src = mputstr(src, " }");
478 }
479 src = mputstr(src, ";\n");
480 for (size_t i = 0; i < hp_literals.size(); i++) {
481 if (i > 0) src = mputstr(src, ",\n");
482 else src = mputstr(src, "static const HEXSTRING_template ");
483 const char *name = hp_literals.get_nth_elem(i)->c_str();
484 src = mputprintf(src, "%s(%lu, %s_elements)",
485 name, (unsigned long) hp_literals.get_nth_key(i).size(), name);
486 }
487 src = mputstr(src, ";\n");
488 }
489
490 void Module::generate_os_literals(char *&src, char *&hdr)
491 {
492 if (os_literals.size() == 0) return;
493 // indicates whether we have found at least one non-empty octetstring
494 bool is_nonempty = false;
495 bool splitting =
496 CodeGenHelper::GetInstance().get_split_mode() != CodeGenHelper::SPLIT_NONE;
497 for (size_t i = 0; i < os_literals.size(); i++) {
498 const string& str = os_literals.get_nth_key(i);
499 size_t size = str.size();
500 if (size % 2) FATAL_ERROR("Invalid length for an octetstring.");
501 size_t octets = size / 2;
502 if (octets == 0) continue;
503 const char *str_ptr = str.c_str();
504 if (is_nonempty) src = mputstr(src, ",\n");
505 else {
506 src = mputstr(src, "static const unsigned char ");
507 is_nonempty = true;
508 }
509 src = mputprintf(src, "%s_octets[] = { ",
510 os_literals.get_nth_elem(i)->c_str());
511 for (size_t j = 0; j < octets; j++) {
512 if (j > 0) src = mputstr(src, ", ");
513 src = mputprintf(src, "%u", 16 * char_to_hexdigit(str_ptr[2 * j]) +
514 char_to_hexdigit(str_ptr[2 * j + 1]));
515 }
516 src = mputstr(src, " }");
517 }
518 if (is_nonempty) src = mputstr(src, ";\n");
519 for (size_t i = 0; i < os_literals.size(); i++) {
520 if (i > 0) {
521 src = mputstr(src, ",\n");
522 if (splitting) hdr = mputstr(hdr, ",\n");
523 }
524 else {
525 src = mputprintf(src, "%s const OCTETSTRING ",
526 splitting ? "extern" : "static");
527 if (splitting) hdr = mputstr(hdr, "extern const OCTETSTRING ");
528 }
529 size_t octets = os_literals.get_nth_key(i).size() / 2;
530 const char *object_name = os_literals.get_nth_elem(i)->c_str();
531 if (octets > 0) src = mputprintf(src, "%s(%lu, %s_octets)",
532 object_name, (unsigned long) octets, object_name);
533 else src = mputprintf(src, "%s(0, NULL)", object_name);
534 if (splitting) hdr = mputstr(hdr, object_name);
535 }
536 src = mputstr(src, ";\n");
537 if (splitting) hdr = mputstr(hdr, ";\n");
538 }
539
540 void Module::generate_op_literals(char *&src, char *& /*hdr*/)
541 {
542 if (op_literals.size() == 0) return;
543 vector<size_t> pattern_lens;
544 for(size_t i = 0; i < op_literals.size(); i++) {
545 if (i > 0) src = mputstr(src, ",\n");
546 else src = mputstr(src, "static const unsigned short ");
547 src = mputprintf(src, "%s_elements[] = { ",
548 op_literals.get_nth_elem(i)->c_str());
549 const string& str = op_literals.get_nth_key(i);
550 size_t size = str.size();
551 size_t pattern_len = 0;
552 const char *str_ptr = str.c_str();
553 for (size_t j = 0; j < size; j++) {
554 if (j > 0) src = mputstr(src, ", ");
555 unsigned short num;
556 if (str_ptr[j] == '?') num = 256;
557 else if (str_ptr[j] == '*') num = 257;
558 else {
559 // first digit
560 num = 16 * char_to_hexdigit(str_ptr[j]);
561 j++;
562 if (j >= size) FATAL_ERROR("Unexpected end of octetstring pattern.");
563 // second digit
564 num += char_to_hexdigit(str_ptr[j]);
565 }
566 src = mputprintf(src, "%u", num);
567 pattern_len++;
568 }
569 src = mputstr(src, " }");
570 pattern_lens.add(new size_t(pattern_len));
571 }
572 src = mputstr(src, ";\n");
573 for (size_t i = 0; i < op_literals.size(); i++) {
574 if (i > 0) src = mputstr(src, ",\n");
575 else src = mputstr(src, "static const OCTETSTRING_template ");
576 const char *name = op_literals.get_nth_elem(i)->c_str();
577 src = mputprintf(src, "%s(%lu, %s_elements)",
578 name, (unsigned long) *pattern_lens[i], name);
579 }
580 src = mputstr(src, ";\n");
581 for (size_t i = 0; i < pattern_lens.size(); i++) delete pattern_lens[i];
582 pattern_lens.clear();
583 }
584
585 void Module::generate_cs_literals(char *&src, char *&hdr)
586 {
587 if (cs_literals.size() == 0) return;
588 bool splitting =
589 CodeGenHelper::GetInstance().get_split_mode() != CodeGenHelper::SPLIT_NONE;
590 for (size_t i = 0; i < cs_literals.size(); i++) {
591 const string& str = cs_literals.get_nth_key(i);
592 size_t str_len = str.size();
593 const char *str_ptr = str.c_str();
594 const char *str_name = cs_literals.get_nth_elem(i)->c_str();
595
596 if (i > 0) {
597 src = mputstr(src, ",\n");
598 if (splitting) hdr = mputstr(hdr, ",\n");
599 }
600 else {
601 src = mputprintf(src, "%s const CHARSTRING ",
602 splitting ? "extern" : "static");
603 if (splitting) hdr = mputstr(hdr, "extern const CHARSTRING ");
604 }
605
606 switch (str_len) {
607 case 0:
608 src = mputprintf(src, "%s(0, NULL)", str_name);
609 break;
610 case 1:
611 src = mputprintf(src, "%s('", str_name);
612 src = Code::translate_character(src, *str_ptr, false);
613 src = mputstr(src, "')");
614 break;
615 default:
616 src = mputprintf(src, "%s(%lu, \"", str_name, (unsigned long) str_len);
617 // Note: Code::translate_string() is not suitable because the string
618 // may contain NUL characters at which translate_string() stops
619 // immediately
620 for (size_t j = 0; j < str_len; j++)
621 src = Code::translate_character(src, str_ptr[j], true);
622 src = mputstr(src, "\")");
623 break;
624 } // switch
625 if (splitting) hdr = mputstr(hdr, str_name);
626 }
627 src = mputstr(src, ";\n");
628 if (splitting) hdr = mputstr(hdr, ";\n");
629 }
630
631 void Module::generate_pp_literals(char *&src, char *&) // padding patterns
632 {
633 if (pp_literals.size() == 0) return;
634 for (size_t i = 0; i < pp_literals.size(); i++) {
635 const string& pattern = pp_literals.get_nth_key(i);
636 size_t pattern_len = pattern.size();
637 const char *pattern_ptr = pattern.c_str();
638 if (i > 0) src = mputstr(src, ",\n");
639 else src = mputstr(src, "static const unsigned char ");
640 src = mputprintf(src, "%s[] = { ", pp_literals.get_nth_elem(i)->c_str());
641 if (pattern_len % 8 != 0) FATAL_ERROR("Module::generate_pp_literals()");
642 size_t nof_octets = pattern_len / 8;
643 for (size_t j = 0; j < nof_octets; j++) {
644 if (j > 0) src = mputstr(src, ", ");
645 unsigned char octet = 0;
646 for (size_t k = 0; k < 8; k++) {
647 // take the octets in reverse order
648 // MSB is the first character of the string
649 octet <<= 1;
650 if (pattern_ptr[8 * (nof_octets - j - 1) + k] == '1') octet |= 0x01;
651 }
652 src = mputprintf(src, "0x%02x", octet);
653 }
654 src = mputstr(src, " }");
655 }
656 src = mputstr(src, ";\n");
657 }
658
659 void Module::generate_mp_literals(char *&src, char *&) // matching patt.
660 {
661 if (mp_literals.size() == 0) return;
662 for (size_t i = 0; i < mp_literals.size(); i++) {
663 const string& str = mp_literals.get_nth_key(i);
664 if (str.size() < 1) FATAL_ERROR("Module::generate_mp_literals()");
665 const char *str_ptr = str.c_str();
666
667 if (i > 0) src = mputstr(src, ",\n");
668 else src = mputstr(src, "static const Token_Match ");
669
670 src = mputprintf(src, "%s(\"", mp_literals.get_nth_elem(i)->c_str());
671 src = Code::translate_string(src, str_ptr + 1);
672 // The first character of the string is case-sensitiveness flag:
673 // 'I' for yes, 'N' for no,
674 // 'F' for fixed string matching which is always case sensitive.
675 src = mputprintf(src, "\", %s%s)", (str_ptr[0]!='N') ? "TRUE" : "FALSE",
676 (str_ptr[0] == 'F') ? ", TRUE" : "");
677 }
678 src = mputstr(src, ";\n");
679 }
680
681 void Module::generate_us_literals(char *&src, char *&hdr) // univ.cs
682 {
683 size_t n_literals = us_literals.size();
684 if (n_literals == 0) return;
685 bool array_needed = false;
686 bool splitting =
687 CodeGenHelper::GetInstance().get_split_mode() != CodeGenHelper::SPLIT_NONE;
688 for (size_t i = 0; i < n_literals; i++) {
689 const ustring& value = us_literals.get_nth_key(i);
690 size_t value_size = value.size();
691 if (value_size < 2) continue;
692 if (array_needed) src = mputstr(src, ",\n");
693 else {
694 src = mputstr(src, "static const universal_char ");
695 array_needed = true;
696 }
697 src = mputprintf(src, "%s_uchars[] = { ",
698 us_literals.get_nth_elem(i)->c_str());
699 const ustring::universal_char *uchars_ptr = value.u_str();
700 for (size_t j = 0; j < value_size; j++) {
701 if (j > 0) src = mputstr(src, ", ");
702 src = mputprintf(src, "{ %u, %u, %u, %u }", uchars_ptr[j].group,
703 uchars_ptr[j].plane, uchars_ptr[j].row, uchars_ptr[j].cell);
704 }
705 src = mputstr(src, " }");
706 }
707 if (array_needed) src = mputstr(src, ";\n");
708 for (size_t i = 0; i < n_literals; i++) {
709 if (i > 0) {
710 src = mputstr(src, ",\n");
711 if (splitting) hdr = mputstr(hdr, ",\n");
712 }
713 else {
714 src = mputprintf(src, "%s const UNIVERSAL_CHARSTRING ",
715 splitting ? "extern" : "static");
716 if (splitting) hdr = mputstr(hdr, "extern const UNIVERSAL_CHARSTRING ");
717 }
718 const char *value_name = us_literals.get_nth_elem(i)->c_str();
719 const ustring& value = us_literals.get_nth_key(i);
720 size_t value_size = value.size();
721 switch (value_size) {
722 case 0:
723 src = mputprintf(src, "%s(0, (const universal_char*)NULL)", value_name);
724 break;
725 case 1: {
726 const ustring::universal_char& uchar = value.u_str()[0];
727 src = mputprintf(src, "%s(%u, %u, %u, %u)", value_name,
728 uchar.group, uchar.plane, uchar.row, uchar.cell);
729 break; }
730 default:
731 src = mputprintf(src, "%s(%lu, %s_uchars)", value_name,
732 (unsigned long) value_size, value_name);
733 break;
734 }
735 if (splitting) hdr = mputstr(hdr, value_name);
736 }
737 src = mputstr(src, ";\n");
738 if (splitting) hdr = mputstr(hdr, ";\n");
739 }
740
741 void Module::generate_oid_literals(char *&src, char *& /*hdr*/)
742 {
743 if (oid_literals.size() == 0) return;
744 for (size_t i = 0; i < oid_literals.size(); i++) {
745 if (i > 0) src = mputstr(src, ",\n");
746 else src = mputstr(src, "static const OBJID::objid_element ");
747
748 src = mputprintf(src, "%s_comps[] = { %s }",
749 oid_literals.get_nth_elem(i)->oid_id.c_str(),
750 oid_literals.get_nth_key(i).c_str());
751 }
752 src = mputstr(src, ";\n");
753 for(size_t i = 0; i < oid_literals.size(); i++) {
754 const OID_literal *litstruct = oid_literals.get_nth_elem(i);
755
756 if (i > 0) src = mputstr(src, ",\n");
757 else src = mputstr(src, "static const OBJID ");
758
759 src = mputprintf(src, "%s(%lu, %s_comps)",
760 litstruct->oid_id.c_str(), (unsigned long) litstruct->nof_elems,
761 litstruct->oid_id.c_str());
762 }
763 src = mputstr(src, ";\n");
764 }
765
766 void Module::generate_functions(output_struct *output)
767 {
768 bool tcov_enabled = tcov_file_name && in_tcov_files(get_filename());
769 bool has_pre_init_before_tcov = output->functions.pre_init != NULL;
770 if (tcov_enabled) {
771 output->functions.pre_init = mputprintf(output->functions.pre_init,
772 "TTCN_Location_Statistics::init_file_lines(\"%s\", effective_module_lines, sizeof(effective_module_lines) / sizeof(int));\n" \
773 "TTCN_Location_Statistics::init_file_functions(\"%s\", effective_module_functions, sizeof(effective_module_functions) / sizeof(char *));\n",
774 get_tcov_file_name(get_filename()), get_tcov_file_name(get_filename()));
775 }
776 // pre_init function
777 bool has_pre_init = false;
a38c6d4c 778 bool profiled = MOD_TTCN == get_moduletype() && is_file_profiled(get_filename());
779 // always generate pre_init_module if the file is profiled
780 if (output->functions.pre_init || profiled) {
970ed795
EL
781 output->source.static_function_prototypes =
782 mputstr(output->source.static_function_prototypes,
783 "static void pre_init_module();\n");
784 output->source.static_function_bodies = mputstr(output->source.static_function_bodies,
785 "static void pre_init_module()\n"
786 "{\n");
787 if (include_location_info) {
788 output->source.static_function_bodies =
789 mputstr(output->source.static_function_bodies,
790 (tcov_enabled && has_pre_init_before_tcov) ? "TTCN_Location_Statistics current_location(\""
791 : "TTCN_Location current_location(\"");
792 output->source.static_function_bodies =
793 Code::translate_string(output->source.static_function_bodies, (tcov_enabled && has_pre_init_before_tcov) ? get_tcov_file_name(get_filename()) : get_filename());
794 output->source.static_function_bodies =
795 mputprintf(output->source.static_function_bodies,
796 (tcov_enabled && has_pre_init_before_tcov) ? "\", 0, TTCN_Location_Statistics::LOCATION_UNKNOWN, \"%s\");\n"
797 : "\", 0, TTCN_Location::LOCATION_UNKNOWN, \"%s\");\n", get_modid().get_dispname().c_str());
798 if (tcov_enabled && has_pre_init_before_tcov) {
799 effective_module_lines =
800 mputprintf(effective_module_lines, "%s0",
801 (effective_module_lines ? ", " : ""));
802 effective_module_functions =
803 mputprintf(effective_module_functions, "%s\"%s\"",
804 (effective_module_functions ? ", " : ""), get_modid().get_dispname().c_str());
805 }
a38c6d4c 806 if (profiled) {
af710487 807 output->source.static_function_bodies = mputprintf(output->source.static_function_bodies,
a38c6d4c 808 "%s::init_ttcn3_profiler();\n"
af710487 809 "TTCN3_Stack_Depth stack_depth;\n"
a38c6d4c 810 "ttcn3_prof.execute_line(\"%s\", 0);\n", get_modid().get_name().c_str(), get_filename());
af710487 811 }
970ed795
EL
812 }
813 output->source.static_function_bodies =
814 mputstr(output->source.static_function_bodies, output->functions.pre_init);
815 output->source.static_function_bodies =
816 mputstr(output->source.static_function_bodies, "}\n\n");
817 Free(output->functions.pre_init);
818 output->functions.pre_init = NULL;
819 has_pre_init = true;
820 }
821 bool has_post_init_before_tcov = output->functions.post_init != NULL;
822 // post_init function
823 bool has_post_init = false;
824 if (output->functions.post_init) {
825 output->source.static_function_prototypes = mputstr(output->source.static_function_prototypes,
826 "static void post_init_module();\n");
827 output->source.static_function_bodies = mputstr(output->source.static_function_bodies,
828 "static void post_init_module()\n"
829 "{\n");
830 if (include_location_info) {
831 output->source.static_function_bodies =
832 mputstr(output->source.static_function_bodies,
833 (tcov_enabled && has_post_init_before_tcov) ? "TTCN_Location_Statistics current_location(\""
834 : "TTCN_Location current_location(\"");
835 output->source.static_function_bodies =
836 Code::translate_string(output->source.static_function_bodies, (tcov_enabled && has_post_init_before_tcov) ? get_tcov_file_name(get_filename()) : get_filename());
837 output->source.static_function_bodies =
838 mputprintf(output->source.static_function_bodies,
839 (tcov_enabled && has_post_init_before_tcov) ? "\", 0, TTCN_Location_Statistics::LOCATION_UNKNOWN, \"%s\");\n"
840 : "\", 0, TTCN_Location::LOCATION_UNKNOWN, \"%s\");\n", get_modid().get_dispname().c_str());
841 if (tcov_enabled && has_post_init_before_tcov) {
842 effective_module_lines =
843 mputprintf(effective_module_lines, "%s0",
844 (effective_module_lines ? ", " : ""));
845 effective_module_functions =
846 mputprintf(effective_module_functions, "%s\"%s\"",
847 (effective_module_functions ? ", " : ""), get_modid().get_dispname().c_str());
848 }
a38c6d4c 849 if (MOD_TTCN == get_moduletype() && is_file_profiled(get_filename())) {
af710487 850 output->source.static_function_bodies = mputprintf(output->source.static_function_bodies,
851 "TTCN3_Stack_Depth stack_depth;\n"
a38c6d4c 852 "ttcn3_prof.execute_line(\"%s\", 0);\n", get_filename());
af710487 853 }
970ed795
EL
854 }
855 output->source.static_function_bodies =
856 mputstr(output->source.static_function_bodies, output->functions.post_init);
857 output->source.static_function_bodies =
858 mputstr(output->source.static_function_bodies, "}\n\n");
859 Free(output->functions.post_init);
860 output->functions.post_init = NULL;
861 has_post_init = true;
862 }
863 // set_param function
864 bool has_set_param;
865 if (output->functions.set_param) {
866 output->source.static_function_prototypes = mputstr(output->source.static_function_prototypes,
867 "static boolean set_module_param(Module_Param& param);\n");
868 output->source.static_function_bodies = mputstr(output->source.static_function_bodies,
869 "static boolean set_module_param(Module_Param& param)\n"
870 "{\n"
871 "const char* const par_name = param.get_id()->get_current_name();\n");
872 output->source.static_function_bodies =
873 mputstr(output->source.static_function_bodies, output->functions.set_param);
874 output->source.static_function_bodies =
875 mputstr(output->source.static_function_bodies, "return FALSE;\n"
876 "}\n\n");
877 Free(output->functions.set_param);
878 output->functions.set_param = NULL;
879 has_set_param = true;
880 } else has_set_param = false;
3abe9331 881 // get_param function
882 bool has_get_param;
883 if (output->functions.get_param) {
884 output->source.static_function_prototypes = mputstr(output->source.static_function_prototypes,
885 "static Module_Param* get_module_param(Module_Param_Name& param_name);\n");
886 output->source.static_function_bodies = mputstr(output->source.static_function_bodies,
887 "static Module_Param* get_module_param(Module_Param_Name& param_name)\n"
888 "{\n"
889 "const char* const par_name = param_name.get_current_name();\n");
890 output->source.static_function_bodies =
891 mputstr(output->source.static_function_bodies, output->functions.get_param);
892 output->source.static_function_bodies =
893 mputstr(output->source.static_function_bodies, "return NULL;\n"
894 "}\n\n");
895 Free(output->functions.get_param);
896 output->functions.get_param = NULL;
897 has_get_param = true;
898 } else has_get_param = false;
970ed795
EL
899 // log_param function
900 bool has_log_param;
901 if (output->functions.log_param) {
902 output->source.static_function_prototypes = mputstr(output->source.static_function_prototypes,
903 "static void log_module_param();\n");
904 output->source.static_function_bodies = mputstr(output->source.static_function_bodies,
905 "static void log_module_param()\n"
906 "{\n");
907 output->source.static_function_bodies =
908 mputstr(output->source.static_function_bodies, output->functions.log_param);
909 output->source.static_function_bodies = mputstr(output->source.static_function_bodies,
910 "}\n\n");
911 Free(output->functions.log_param);
912 output->functions.log_param = NULL;
913 has_log_param = true;
914 } else has_log_param = false;
915 // init_comp function
916 bool has_init_comp;
917 if (output->functions.init_comp) {
918 output->source.static_function_prototypes =
919 mputstr(output->source.static_function_prototypes,
920 "static boolean init_comp_type("
921 "const char *component_type, boolean init_base_comps);\n");
922 output->source.static_function_bodies =
923 mputstr(output->source.static_function_bodies,
924 "static boolean init_comp_type(const char *component_type, "
925 "boolean init_base_comps)\n"
926 "{\n(void)init_base_comps;\n");
927 output->source.static_function_bodies =
928 mputstr(output->source.static_function_bodies,
929 output->functions.init_comp);
930 output->source.static_function_bodies =
931 mputstr(output->source.static_function_bodies, "return FALSE;\n"
932 "}\n\n");
933 Free(output->functions.init_comp);
934 output->functions.init_comp = NULL;
935 has_init_comp = true;
936 } else has_init_comp = false;
937 // start function
938 bool has_start;
939 if (output->functions.start) {
940 output->source.static_function_prototypes = mputstr(output->source.static_function_prototypes,
941 "static boolean start_ptc_function(const char *function_name, "
942 "Text_Buf& function_arguments);\n");
943 output->source.static_function_bodies = mputstr(output->source.static_function_bodies,
944 "static boolean start_ptc_function(const char *function_name, "
945 "Text_Buf& function_arguments)\n"
946 "{\n");
947 output->source.static_function_bodies =
948 mputstr(output->source.static_function_bodies, output->functions.start);
949 output->source.static_function_bodies =
950 mputstr(output->source.static_function_bodies, "return FALSE;\n"
951 "}\n\n");
952 Free(output->functions.start);
953 output->functions.start = NULL;
954 has_start = true;
955 } else has_start = false;
956 // control part
957 bool has_control;
958 if (output->functions.control) {
959 output->source.static_function_prototypes = mputstr(output->source.static_function_prototypes,
960 "static void module_control_part();\n");
961 output->source.static_function_bodies = mputstr(output->source.static_function_bodies,
962 "static void module_control_part()\n"
963 "{\n");
964 output->source.static_function_bodies =
965 mputstr(output->source.static_function_bodies, output->functions.control);
966 output->source.static_function_bodies =
967 mputstr(output->source.static_function_bodies, "}\n\n");
968 Free(output->functions.control);
969 output->functions.control = NULL;
970 has_control = true;
971 } else has_control = false;
972 // module checksum
973 if (has_checksum) {
974 output->source.string_literals = mputstr(output->source.string_literals,
975 "static const unsigned char module_checksum[] = {");
976 for (size_t i = 0; i < sizeof(module_checksum); i++) {
977 if (i > 0) output->source.string_literals =
978 mputc(output->source.string_literals, ',');
979 output->source.string_literals =
980 mputprintf(output->source.string_literals, " 0x%02x",
981 module_checksum[i]);
982 }
983 output->source.string_literals = mputstr(output->source.string_literals,
984 " };\n");
985 }
986 const char *module_name = modid->get_name().c_str();
987
988 // XML namespaces. Written in the order they are stored:
989 // sorted ASCIIbetically by the prefix.
990 // Not all namespaces are used by every module. Unfortunately, the array
991 // (which has the same size in all modules) cannot be compacted, because
992 // the indexes have already been used when the XER descriptors were written.
993 // All we can do is store NULLs for the unused namespaces.
994 size_t num_xml_namespaces = namespaces.size();
995 if (moduletype == MOD_TTCN) { //TODO remove this when ASN.1 gets EXER
996 output->source.global_vars = mputprintf(output->source.global_vars,
997#ifndef NDEBUG
998 "// written by %s in " __FILE__ " at %d\n"
999#endif
1000 "static const size_t num_namespaces = %lu;\n"
1001#ifndef NDEBUG
1002 , __FUNCTION__, __LINE__
1003#endif
1004 , (unsigned long)num_xml_namespaces
1005 );
1006 if (num_xml_namespaces != 0 || (control_ns && control_ns_prefix)) {
1007 output->source.global_vars = mputstr(output->source.global_vars,
1008 "static const namespace_t xml_namespaces[num_namespaces+1] = {\n");
1009 for (size_t i=0; i < namespaces.size(); ++i) {
1010 if (used_namespaces.has_key(i)) {
1011 output->source.global_vars = mputprintf(output->source.global_vars,
1012 " { \"%s\", \"%s\" },\n", // ns, then prefix
1013 namespaces.get_nth_elem(i), namespaces.get_nth_key(i).c_str());
1014 }
1015 else {
1016 output->source.global_vars = mputstr(output->source.global_vars,
1017 " { NULL, NULL },\n"); // not used in this module
1018 }
1019 } // next namespace
1020 output->source.global_vars = mputprintf(output->source.global_vars,
1021 " { \"%s\", \"%s\" }\n};\n\n",
1022 (control_ns ? control_ns : ""),
1023 (control_ns_prefix ? control_ns_prefix : ""));
1024 } // if there are namespaces
1025 } // if TTCN
1026
1027
1028 // module object
1029 output->header.global_vars = mputprintf(output->header.global_vars,
1030 "extern TTCN_Module %s;\n",
1031 "module_object");
1032
1033 output->source.global_vars = mputprintf(output->source.global_vars,
1034 "TTCN_Module %s(\"%s\", __DATE__, __TIME__, %s, %s",
1035 "module_object",
1036
1037 modid->get_dispname().c_str(),
1038 (has_checksum ? "module_checksum" : "NULL"),
1039 has_pre_init ? "pre_init_module" : "NULL");
1040
1041 if (moduletype == MOD_TTCN) {
1042 // TTCN-3 specific function pointers
1043 if (product_number == NULL) {
1044 output->source.global_vars = mputstr(output->source.global_vars, ", NULL");
1045 } else {
1046 output->source.global_vars = mputprintf(output->source.global_vars, ", \"%s\"", product_number);
1047 }
1048 string extra_str = extra ? ( string('"') + extra + string('"') ) : string("NULL");
1049 output->source.global_vars = mputprintf(output->source.global_vars,
3abe9331 1050 ", %uU, %uU, %uU, %uU, %s, %luLU, %s, %s, %s, %s, %s, %s, %s, %s",
970ed795
EL
1051 suffix, release, patch, build, extra_str.c_str(),
1052 (unsigned long)num_xml_namespaces,
1053 ((num_xml_namespaces || (control_ns && control_ns_prefix)) ? "xml_namespaces" : "0"),
1054 has_post_init ? "post_init_module" : "NULL",
1055 has_set_param ? "set_module_param" : "NULL",
3abe9331 1056 has_get_param ? "get_module_param" : "NULL",
970ed795
EL
1057 has_log_param ? "log_module_param" : "NULL",
1058 has_init_comp ? "init_comp_type" : "NULL",
1059 has_start ? "start_ptc_function" : "NULL",
1060 has_control ? "module_control_part" : "NULL");
1061 } else {
1062 // self checks for ASN.1 modules
1063 if (has_post_init)
1064 FATAL_ERROR("Module::generate_functions(): post_init function in ASN.1 module");
1065 if (has_set_param)
1066 FATAL_ERROR("Module::generate_functions(): set_param function in ASN.1 module");
3abe9331 1067 if (has_get_param)
1068 FATAL_ERROR("Module::generate_functions(): get_param function in ASN.1 module");
970ed795
EL
1069 if (has_log_param)
1070 FATAL_ERROR("Module::generate_functions(): log_param function in ASN.1 module");
1071 if (has_init_comp)
1072 FATAL_ERROR("Module::generate_functions(): init_comp function in ASN.1 module");
1073 if (has_start)
1074 FATAL_ERROR("Module::generate_functions(): startable function in ASN.1 module");
1075 if (has_control)
1076 FATAL_ERROR("Module::generate_functions(): control part in ASN.1 module");
1077 }
1078 output->source.global_vars = mputstr(output->source.global_vars, ");\n");
1079 // #include into the source file
1080 output->source.includes = mputprintf(output->source.includes,
1081 "#include \"%s.hh\"\n",
1082 duplicate_underscores ? module_name : modid->get_ttcnname().c_str());
1083
1084 output->source.global_vars = mputprintf(output->source.global_vars,
1085 "\nstatic const RuntimeVersionChecker ver_checker("
1086 " current_runtime_version.requires_major_version_%d,\n"
1087 " current_runtime_version.requires_minor_version_%d,\n"
1088 " current_runtime_version.requires_patch_level_%d,"
1089 " current_runtime_version.requires_runtime_%d);\n",
1090 TTCN3_MAJOR, TTCN3_MINOR, TTCN3_PATCHLEVEL, use_runtime_2 ? 2 : 1
1091 );
1092 if (tcov_enabled) {
1093 output->source.global_vars = mputprintf(output->source.global_vars,
1094 "\nstatic const int effective_module_lines[] = { %s };\n" \
1095 "static const char *effective_module_functions[] = { %s };\n",
1096 effective_module_lines ? static_cast<const char *>(effective_module_lines) : "",
1097 effective_module_functions ? static_cast<const char *>(effective_module_functions) : "");
1098 }
1099 }
1100
1101 void Module::generate_conversion_functions(output_struct *output)
1102 {
1103 for (size_t i = 0; i < type_conv_v.size(); i++)
1104 type_conv_v[i]
1105 ->gen_conv_func(&output->source.static_conversion_function_prototypes,
1106 &output->source.static_conversion_function_bodies,
1107 this);
1108 }
1109
1110 string Module::add_literal(map<string, string>& literals, const string& str,
1111 const char *prefix)
1112 {
1113 if (literals.has_key(str)) return *literals[str];
1114 else {
1115 string *literal = new string(prefix+Int2string(literals.size()));
1116 literals.add(str, literal);
1117 return *literal;
1118 }
1119 }
1120
1121 void Module::clear_literals(map<string, string>& literals)
1122 {
1123 for (size_t i = 0; i < literals.size(); i++)
1124 delete literals.get_nth_elem(i);
1125 literals.clear();
1126 }
1127
1128 map<string, const char> Module::namespaces;
1129 map<string, const char> Module::invented_prefixes;
1130 size_t Module::default_namespace_attempt = 0;
1131 size_t Module::replacement_for_empty_prefix = (size_t)-1;
1132
1133 Module::Module(moduletype_t p_mt, Identifier *p_modid)
1134 : Scope(), moduletype(p_mt), modid(p_modid),
1135 imp_checked(false), gen_code(false), has_checksum(false),
1136 visible_mods(), module_checksum(),
1137 bs_literals(), bp_literals(), hs_literals(), hp_literals(), os_literals(),
1138 op_literals(), cs_literals(), us_literals(), pp_literals(), mp_literals(),
1139 oid_literals(), tmp_id_count(0),
1140 control_ns(p_mt == MOD_ASN ? mcopystr("urn:oid:2.1.5.2.0.1") : NULL),
1141 control_ns_prefix(p_mt == MOD_ASN ? mcopystr("asn1") : NULL),
1142 // only ASN.1 modules have default control namespace (X.693 amd1, 16.9)
1143 used_namespaces(), type_conv_v(), product_number(NULL),
1144 suffix(0), release(UINT_MAX), patch(UINT_MAX), build(UINT_MAX), extra(NULL)
1145 {
1146 if(!p_modid)
1147 FATAL_ERROR("NULL parameter: Common::Module::Module()");
1148 memset(module_checksum, 0, sizeof(module_checksum));
1149 set_scopeMacro_name(modid->get_dispname());
1150 }
1151
1152 Module::~Module()
1153 {
1154 delete modid;
1155 visible_mods.clear();
1156 clear_literals(bs_literals);
1157 clear_literals(bp_literals);
1158 clear_literals(hs_literals);
1159 clear_literals(hp_literals);
1160 clear_literals(os_literals);
1161 clear_literals(op_literals);
1162 clear_literals(cs_literals);
1163 clear_literals(pp_literals);
1164 clear_literals(mp_literals);
1165 for (size_t i = 0; i < us_literals.size(); i++)
1166 delete us_literals.get_nth_elem(i);
1167 us_literals.clear();
1168 for (size_t i = 0; i < oid_literals.size(); i++)
1169 delete oid_literals.get_nth_elem(i);
1170 oid_literals.clear();
1171 for (size_t i = 0; i < type_conv_v.size(); i++)
1172 delete type_conv_v[i];
1173 type_conv_v.clear();
1174 Free(control_ns);
1175 Free(control_ns_prefix);
1176 used_namespaces.clear(); // all the values are NULL, no need to free
1177 // static members below; repeated clear()s are redundant but harmless
1178 namespaces.clear();
1179 invented_prefixes.clear();
1180 Free(product_number);
1181 Free(extra);
1182 }
1183
1184 Type *Module::get_address_type()
1185 {
1186 FATAL_ERROR("Common::Module::get_address_type()");
1187 return 0;
1188 }
1189
1190 string Module::add_ustring_literal(const ustring& ustr)
1191 {
1192 if (us_literals.has_key(ustr)) return *us_literals[ustr];
1193 else {
1194 string *literal = new string("us_" + Int2string(us_literals.size()));
1195 us_literals.add(ustr, literal);
1196 return *literal;
1197 }
1198 }
1199
1200 string Module::add_objid_literal(const string& oi_str, const size_t nof_elems)
1201 {
1202 if(oid_literals.has_key(oi_str)) return oid_literals[oi_str]->oid_id;
1203 else {
1204 OID_literal *oi_struct = new OID_literal;
1205 oi_struct->nof_elems = nof_elems;
1206 oi_struct->oid_id = "oi_" + Int2string(oid_literals.size());
1207 oid_literals.add(oi_str, oi_struct);
1208 return oi_struct->oid_id;
1209 }
1210 }
1211
1212 void Module::add_type_conv(TypeConv *p_conv)
1213 {
1214 if (p_conv == NULL) FATAL_ERROR("Module::add_type_conv()");
1215 Type *p_from_type = p_conv->get_from_type();
1216 Type *p_to_type = p_conv->get_to_type();
1217 if (!p_from_type->is_structured_type()
1218 || !p_to_type->is_structured_type())
1219 FATAL_ERROR("Module::add_type_conv()");
1220 if (p_from_type == p_to_type) {
1221 // Never add the same types.
1222 delete p_conv;
1223 return;
1224 }
1225 for (size_t i = 0; i < type_conv_v.size(); i++) {
1226 TypeConv *conv = type_conv_v[i];
1227 if (conv->get_from_type() == p_from_type
1228 && conv->get_to_type() == p_to_type
1229 && conv->is_temp() == p_conv->is_temp()) {
1230 // Same pair of types, both for values or templates. We're the
1231 // owners, deallocate.
1232 delete p_conv;
1233 return;
1234 }
1235 }
1236 type_conv_v.add(p_conv);
1237 }
1238
1239 bool Module::needs_type_conv(Type *p_from_type, Type *p_to_type) const
1240 {
1241 for (size_t i = 0; i < type_conv_v.size(); i++) {
1242 TypeConv *conv = type_conv_v[i];
1243 if (conv->get_from_type() == p_from_type
1244 && conv->get_to_type() == p_to_type)
1245 return true;
1246 }
1247 return false;
1248 }
1249
1250 void Module::chk_recursive(module_set_t& checked_modules)
1251 {
1252 if (checked_modules.has_key(this)) return;
1253 // this must be added to the set at the beginning
1254 // in order to deal with circular imports
1255 checked_modules.add(this, 0);
1256 // check the imported modules first
1257 size_t nof_visible_mods = visible_mods.size();
1258 for (size_t i = 0; i < nof_visible_mods; i++) {
1259 Module *m = visible_mods.get_nth_key(i);
1260 if (m != this) m->chk_recursive(checked_modules);
1261 }
1262 // then check the module itself
1263 chk(); // this is the only virtual call
1264 }
1265
1266 bool Module::is_visible(Module *m)
1267 {
1268 collect_visible_mods();
1269 return visible_mods.has_key(m);
1270 }
1271
1272 void Module::get_visible_mods(module_set_t& p_visible_mods)
1273 {
1274 if (visible_mods.has_key(this)) {
1275 size_t nof_visible_mods = visible_mods.size();
1276 for (size_t i = 0; i < nof_visible_mods; i++) {
1277 Module *m = visible_mods.get_nth_key(i);
1278 if (!p_visible_mods.has_key(m)) p_visible_mods.add(m, 0);
1279 }
1280 } else {
1281 get_imported_mods(p_visible_mods);
1282 }
1283 }
1284
1285 void Module::write_checksum()
1286 {
1287 fprintf(stderr, "%-18s ", modid->get_dispname().c_str());
1288 switch (moduletype) {
1289 case MOD_TTCN: fprintf(stderr, "%-15s ", "TTCN-3"); break;
1290 case MOD_ASN: fprintf(stderr, "%-15s ", "ASN.1"); break;
1291 case MOD_UNKNOWN: fprintf(stderr, "%-15s ", "OTHER"); break;
1292 }
1293
1294 if (!has_checksum) {
1295 fputc('\n', stderr);
1296 return;
1297 }
1298
1299 size_t nof_checksum = sizeof(module_checksum);
1300 for (size_t i = 0; i < nof_checksum; i++) {
1301 fprintf(stderr, "%02x", module_checksum[i]);
1302 }
1303
1304 if (release <= 999999 && patch < 30 && build < 100) {
1305 char *product_identifier =
1306 get_product_identifier(product_number, suffix, release, patch, build, extra);
1307 fprintf(stderr, " %s", product_identifier);
1308 Free(product_identifier);
1309 }
1310
1311 fputc('\n', stderr);
1312 }
1313
1314 char* Module::get_product_identifier(const char* product_number,
1315 const unsigned int suffix, unsigned int release, unsigned int patch,
1316 unsigned int build, const char* extra)
1317 {
1318 expstring_t ret_val = memptystr();
1319 if ( product_number == NULL
1320 && suffix == UINT_MAX
1321 && release == UINT_MAX
1322 && patch == UINT_MAX
1323 && build == UINT_MAX) {
1324 ret_val = mputstr(ret_val, "<RnXnn>");
1325 return ret_val;
1326 }
1327 if (product_number != NULL) {
1328 ret_val = mputstr(ret_val, product_number);
1329 if (suffix != 0) {
1330 ret_val = mputprintf(ret_val, "/%d", suffix);
1331 }
1332 ret_val = mputc(ret_val, ' ');
1333 }
1334
1335 char* build_str = buildstr(build);
1336 ret_val = mputprintf(ret_val, "R%u%c%s%s", release, eri(patch), build_str, extra ? extra : "");
1337 Free(build_str);
1338 return ret_val;
1339 }
1340
1341 void Module::collect_visible_mods()
1342 {
1343 if (!visible_mods.has_key(this)) {
1344 get_imported_mods(visible_mods);
1345 if (!visible_mods.has_key(this)) visible_mods.add(this, 0);
1346 }
1347 }
1348
1349 void Module::set_checksum(size_t checksum_len,
1350 const unsigned char* checksum_ptr)
1351 {
1352 if (checksum_len != sizeof(module_checksum))
1353 FATAL_ERROR("Module::set_checksum(): invalid length");
1354 memcpy(module_checksum, checksum_ptr, sizeof(module_checksum));
1355 has_checksum = true;
1356 }
1357
1358 void Module::set_controlns(char *ns, char *prefix)
1359 {
1360 Free(control_ns);
1361 control_ns = ns;
1362 Free(control_ns_prefix);
1363 control_ns_prefix = prefix;
1364 }
1365
1366 void Module::get_controlns(const char *&ns, const char *&prefix)
1367 {
1368 ns = control_ns;
1369 prefix = control_ns_prefix;
1370 }
1371
1372 const size_t max_invented_prefixes = 10000;
1373 void Module::add_namespace(const char *new_uri, char *&new_prefix)
1374 {
1375 const bool prefix_is_empty = new_prefix && !*new_prefix;
1376 const string key(new_prefix ? new_prefix : "");
1377 if (new_prefix && !namespaces.has_key(key)) {
1378 namespaces.add(key, new_uri);
1379 if (*new_prefix == 0) { // first add of default namespace
1380 ++default_namespace_attempt;
1381 }
1382 return; // newly added
1383 }
1384 else { // prefix already present (or we are required to invent one)
1385 if (new_prefix) {
1386 const char *uri_value = namespaces[key];
1387 if (!strcmp(uri_value, new_uri)) return; // same URI, same prefix: no-op
1388 }
1389
1390 // prefix already present but different URI,
1391 // or prefix is NULL (which means we must invent a prefix)
1392
1393 if (new_prefix && *new_prefix) {
1394 Free(new_prefix); // prefix is not empty, discard it and start fresh
1395 new_prefix = memptystr();
1396 }
1397
1398 const string uri_key(new_uri);
1399 if (invented_prefixes.has_key(uri_key)) {
1400 // we already made one up for this URI
1401 new_prefix = mputstr(new_prefix, invented_prefixes[uri_key]);
1402 return; // already there
1403 }
1404 else {
1405 // make one up on the spot
1406 size_t iidx = invented_prefixes.size(); // "invented index"
1407 new_prefix = mputprintf(new_prefix, "tq%04lu", (unsigned long)iidx++);
1408 string made_up_prefix(new_prefix);
1409 for (; iidx < max_invented_prefixes; ++iidx) {
1410 if (namespaces.has_key(made_up_prefix)) {
1411 // Some pervert wrote an XSD with a namespace prefix like tq0007!
1412 // Make up another one in the same memory spot.
1413 sprintf(new_prefix, "tq%04lu", (unsigned long)iidx);
1414 made_up_prefix = new_prefix;
1415 }
1416 else break;
1417 }
1418
1419 if (iidx >= max_invented_prefixes) {
1420 Location loc; // no particular location
1421 loc.error("Internal limit: too many assigned prefixes");
1422 return; // not added
1423 }
1424 invented_prefixes.add(uri_key, new_prefix);
1425 namespaces.add(made_up_prefix, new_uri);
1426
1427 // Search for the newly added prefix and remember it.
1428 replacement_for_empty_prefix = namespaces.find_key(made_up_prefix);
1429
1430 if (prefix_is_empty) {
1431 ++default_namespace_attempt;
1432 }
1433 return; // newly added
1434 }
1435 } // if (present)
1436 }
1437
1438 static const string empty_prefix;
1439 void Module::rename_default_namespace()
1440 {
1441 if (default_namespace_attempt < 2) return;
1442 // There was more than one default namespace. However, all but the first
1443 // are already renamed to tq%d.
1444 size_t di = namespaces.find_key(empty_prefix); // keys are prefixes
1445 if (di < namespaces.size()) { // found it
1446 const char *last_remaining_def_namespace = namespaces.get_nth_elem(di);
1447 // we can't change a key, we can only remove and re-add it
1448 namespaces.erase(empty_prefix);
1449
1450 expstring_t empty_prefix_string = NULL; // force a made-up prefix
1451 add_namespace(last_remaining_def_namespace, empty_prefix_string);
1452 Free(empty_prefix_string);
1453 }
1454 else FATAL_ERROR("Module::rename_default_namespace");
1455 }
1456
1457 size_t Module::get_ns_index(const char *prefix)
1458 {
1459 size_t idx = namespaces.find_key(string(prefix));
1460 if (idx >= namespaces.size()) { // not found
1461 // If the the caller asked for the empty prefix and it wasn't found
1462 // because it has been replaced, use the replacement.
1463 if (*prefix == '\0' && replacement_for_empty_prefix != (size_t)-1) {
1464 idx = replacement_for_empty_prefix;
1465 }
1466 else FATAL_ERROR("Module::get_ns_index()");
1467 }
1468
1469 // Remember that the index is used by this module
1470 if (!used_namespaces.has_key(idx)) {
1471 used_namespaces.add(idx, NULL);
1472 }
1473 return idx;
1474 }
1475
1476 string Module::get_temporary_id()
1477 {
1478 static const string tmp_prefix("tmp_");
1479 return tmp_prefix + Int2string(tmp_id_count++);
1480 }
1481
1482 void Module::generate_code(CodeGenHelper& cgh)
1483 {
1484 if (!gen_code) {
1485 nof_notupdated_files += 2;
1486 DEBUG(1, "Code not generated for module `%s'.",
1487 modid->get_dispname().c_str());
1488 return;
1489 }
1490 DEBUG(1, "Generating code for module `%s'.",
1491 modid->get_dispname().c_str());
1492
1493 // TODO: Always assume to have circular imports until
1494 // full program optimization is available,
1495 // this increases the size of the generated code,
1496 // but otherwise it is possible to create uncompilable code:
1497 // 1) let the project of module A and B refer to each other,
1498 // 2) A refers B, and compile A
1499 // 3) edit B to refer to A and compile it ...
1500 // As the code for A can not be rewritten the code will not compile
1501 cgh.add_module(modid->get_name(), modid->get_ttcnname(),
1502 moduletype == MOD_TTCN, true);
1503 cgh.set_current_module(modid->get_ttcnname());
1504
1505 // language specific parts (definitions, imports, etc.)
1506 //generate_code_internal(&target); <- needed to pass cgh
1507 generate_code_internal(cgh);
a38c6d4c 1508
1509 output_struct* output = cgh.get_current_outputstruct();
970ed795
EL
1510
1511 // string literals
a38c6d4c 1512 generate_literals(output);
970ed795 1513 // module level entry points
a38c6d4c 1514 generate_functions(output);
970ed795 1515 // type conversion functions for type compatibility
a38c6d4c 1516 generate_conversion_functions(output);
1517
1518 /* generate the initializer function for the TTCN-3 profiler
1519 * (this is done at the end of the code generation, to make sure all code
1520 * lines have been added to the profiler database) */
1521 if (is_file_profiled(get_filename())) {
1522 output->source.global_vars = mputstr(output->source.global_vars,
1523 "\n/* Initializing TTCN-3 profiler */\n"
1524 "void init_ttcn3_profiler()\n"
1525 "{\n");
1526 char* function_name = 0;
1527 int line_no = -1;
1528 while(get_profiler_code_line(get_filename(), &function_name, &line_no)) {
1529 output->source.global_vars = mputprintf(output->source.global_vars,
1530 " ttcn3_prof.create_line(ttcn3_prof.get_element(\"%s\"), %d);\n",
1531 get_filename(), line_no);
1532 if (0 != function_name) {
1533 output->source.global_vars = mputprintf(output->source.global_vars,
1534 " ttcn3_prof.create_function(ttcn3_prof.get_element(\"%s\"), %d, \"%s\");\n",
1535 get_filename(), line_no, function_name);
1536 }
1537 }
1538 output->source.global_vars = mputstr(output->source.global_vars, "}\n\n");
1539 }
970ed795
EL
1540 }
1541
1542 void Module::dump(unsigned level) const
1543 {
1544 DEBUG(level, "Module: %s", get_modid().get_dispname().c_str());
1545 }
1546
1547 // =================================
1548 // ===== Assignments
1549 // =================================
1550
1551 Assignments *Assignments::get_scope_asss()
1552 {
1553 return this;
1554 }
1555
1556 Assignment *Assignments::get_ass_bySRef(Ref_simple *p_ref)
1557 {
1558 if (!p_ref || !parent_scope)
1559 FATAL_ERROR("NULL parameter: Common::Assignments::get_ass_bySRef()");
1560 if (!p_ref->get_modid()) {
1561 const Identifier *id = p_ref->get_id();
1562 if (id && has_local_ass_withId(*id)) return get_local_ass_byId(*id);
1563 }
1564 return parent_scope->get_ass_bySRef(p_ref);
1565 }
1566
1567 bool Assignments::has_ass_withId(const Identifier& p_id)
1568 {
1569 if (has_local_ass_withId(p_id)) return true;
1570 else if (parent_scope) return parent_scope->has_ass_withId(p_id);
1571 else return false;
1572 }
1573
1574 // =================================
1575 // ===== Assignment
1576 // =================================
1577
1578 Assignment::Assignment(asstype_t p_asstype, Identifier *p_id)
1579 : asstype(p_asstype), id(p_id), my_scope(0), checked(false),
1580 visibilitytype(PUBLIC)
1581 {
1582 if (!id) FATAL_ERROR("Assignment::Assignment(): NULL parameter");
1583 }
1584
1585 Assignment::Assignment(const Assignment& p)
1586 : Node(p), Location(p), asstype(p.asstype), id(p.id->clone()), my_scope(0),
1587 checked(false), visibilitytype(p.visibilitytype)
1588 {
1589
1590 }
1591
1592 Assignment::~Assignment()
1593 {
1594 delete id;
1595 }
1596
1597 Assignment::asstype_t Assignment::get_asstype() const
1598 {
1599 return asstype;
1600 }
1601
1602 const char *Assignment::get_assname() const
1603 {
1604 switch (get_asstype()) {
1605 case A_TYPE:
1606 return "type";
1607 case A_CONST:
1608 if (my_scope && my_scope->get_scope_mod()->get_moduletype() ==
1609 Module::MOD_ASN) return "value";
1610 else return "constant";
1611 case A_ERROR:
1612 return "erroneous assignment";
1613 case A_OC:
1614 return "information object class";
1615 case A_OBJECT:
1616 return "information object";
1617 case A_OS:
1618 return "information object set";
1619 case A_VS:
1620 return "value set";
1621 case A_EXT_CONST:
1622 return "external constant";
1623 case A_MODULEPAR:
1624 return "module parameter";
1625 case A_MODULEPAR_TEMP:
1626 return "template module parameter";
1627 case A_TEMPLATE:
1628 return "template";
1629 case A_VAR:
1630 return "variable";
1631 case A_VAR_TEMPLATE:
1632 return "template variable";
1633 case A_TIMER:
1634 return "timer";
1635 case A_PORT:
1636 return "port";
1637 case A_FUNCTION:
1638 case A_FUNCTION_RVAL:
1639 case A_FUNCTION_RTEMP:
1640 return "function";
1641 case A_EXT_FUNCTION:
1642 case A_EXT_FUNCTION_RVAL:
1643 case A_EXT_FUNCTION_RTEMP:
1644 return "external function";
1645 case A_ALTSTEP:
1646 return "altstep";
1647 case A_TESTCASE:
1648 return "testcase";
1649 case A_PAR_VAL:
1650 case A_PAR_VAL_IN:
1651 return "value parameter";
1652 case A_PAR_VAL_OUT:
1653 return "`out' value parameter";
1654 case A_PAR_VAL_INOUT:
1655 return "`inout' value parameter";
1656 case A_PAR_TEMPL_IN:
1657 return "template parameter";
1658 case A_PAR_TEMPL_OUT:
1659 return "`out' template parameter";
1660 case A_PAR_TEMPL_INOUT:
1661 return "`inout' template parameter";
1662 case A_PAR_TIMER:
1663 return "timer parameter";
1664 case A_PAR_PORT:
1665 return "port parameter";
1666 default:
1667 return "<unknown>";
1668 }
1669 }
1670
1671 string Assignment::get_description()
1672 {
1673 string ret_val(get_assname());
1674 ret_val += " `";
1675 switch (asstype) {
1676 case A_PAR_VAL:
1677 case A_PAR_VAL_IN:
1678 case A_PAR_VAL_OUT:
1679 case A_PAR_VAL_INOUT:
1680 case A_PAR_TEMPL_IN:
1681 case A_PAR_TEMPL_OUT:
1682 case A_PAR_TEMPL_INOUT:
1683 case A_PAR_TIMER:
1684 case A_PAR_PORT:
1685 // parameter is identified using its id
1686 ret_val += id->get_dispname();
1687 break;
1688 case A_CONST:
1689 case A_TEMPLATE:
1690 case A_VAR:
1691 case A_VAR_TEMPLATE:
1692 case A_TIMER:
1693 // these can be both local and global
1694 if (is_local()) ret_val += id->get_dispname();
1695 else ret_val += get_fullname();
1696 break;
1697 default:
1698 // the rest is always global
1699 ret_val += get_fullname();
1700 }
1701 ret_val += "'";
1702 return ret_val;
1703 }
1704
1705 void Assignment::set_my_scope(Scope *p_scope)
1706 {
1707 my_scope=p_scope;
1708 }
1709
1710 bool Assignment::is_local() const
1711 {
1712 return false;
1713 }
1714
1715 Setting *Assignment::get_Setting()
1716 {
1717 FATAL_ERROR("Common::Assignment::get_Setting()");
1718 return 0;
1719 }
1720
1721 Type *Assignment::get_Type()
1722 {
1723 FATAL_ERROR("Common::Assignment::get_Type()");
1724 return 0;
1725 }
1726
1727 Value *Assignment::get_Value()
1728 {
1729 FATAL_ERROR("Common::Assignment::get_Value()");
1730 return 0;
1731 }
1732
1733 Ttcn::Template *Assignment::get_Template()
1734 {
1735 FATAL_ERROR("Common::Assignment::get_Template()");
1736 return 0;
1737 }
1738
1739 bool Assignment::get_lazy_eval() const
1740 {
1741 FATAL_ERROR("Common::Assignment::get_lazy_eval()");
1742 return false;
1743 }
1744
1745 Ttcn::FormalParList *Assignment::get_FormalParList()
1746 {
1747 return 0;
1748 }
1749
1750 Ttcn::ArrayDimensions *Assignment::get_Dimensions()
1751 {
1752 return 0;
1753 }
1754
1755 Type *Assignment::get_RunsOnType()
1756 {
1757 return 0;
1758 }
1759
1760 void Assignment::chk_ttcn_id()
1761 {
1762 if(!my_scope) return;
1763 if(!get_id().get_has_valid(Identifier::ID_TTCN)
1764 && my_scope->get_parent_scope()==my_scope->get_scope_mod()
1765 // <internal> or <error> ...
1766 && my_scope->get_scope_mod()->get_modid().get_dispname()[0]!='<')
1767 warning("The identifier `%s' is not reachable from TTCN-3",
1768 get_id().get_dispname().c_str());
1769 }
1770
1771 // *this is the (var/const/modulepar/etc.) definition we want to access.
1772 // p_scope is the location from where we want to reach the definition.
1773 string Assignment::get_genname_from_scope(Scope *p_scope,
1774 const char *p_prefix)
1775 {
1776 if (!p_scope || !my_scope)
1777 FATAL_ERROR("Assignment::get_genname_from_scope()");
1778 string ret_val;
1779
1780 Module *my_mod = my_scope->get_scope_mod_gen();
1781 if ((my_mod != p_scope->get_scope_mod_gen()) &&
1782 !Asn::Assignments::is_spec_asss(my_mod)) {
1783 // when the definition is referred from another module
1784 // the reference shall be qualified with the namespace of my module
1785 ret_val = my_mod->get_modid().get_name();
1786 ret_val += "::";
1787 }
1788 if (p_prefix) ret_val += p_prefix;
1789 ret_val += get_genname();
1790 // add the cast to real type if its a lazy formal paramter
1791 switch (asstype) {
1792 case A_PAR_VAL:
1793 case A_PAR_VAL_IN:
1794 case A_PAR_TEMPL_IN:
1795 if (get_lazy_eval() && p_prefix==NULL) {
1796 Type* type = get_Type();
1797 string type_genname = (asstype==A_PAR_TEMPL_IN) ? type->get_genname_template(p_scope) : type->get_genname_value(p_scope);
1798 ret_val = string("((") + type_genname + string("&)") + ret_val + string(")");
1799 }
1800 break;
1801 default:
1802 // nothing to do
1803 break;
1804 }
1805 return ret_val;
1806 }
1807
1808 const char *Assignment::get_module_object_name()
1809 {
1810 if (!my_scope) FATAL_ERROR("Assignment::get_module_object_name()");
1811 return "module_object";
1812 }
1813
1814 void Assignment::use_as_lvalue(const Location&)
1815 {
1816 FATAL_ERROR("Common::Assignment::use_as_lvalue()");
1817 }
1818
1819 void Assignment::generate_code(output_struct *, bool)
1820 {
1821 }
1822
1823 void Assignment::generate_code(CodeGenHelper&)
1824 {
1825 }
1826
1827 void Assignment::dump(unsigned level) const
1828 {
1829 DEBUG(level, "Assignment: %s (%d)",
1830 id->get_dispname().c_str(), asstype);
1831 }
1832
1833 Ttcn::Group* Assignment::get_parent_group()
1834 {
1835 return NULL;
1836 }
1837
1838} // namespace Common
This page took 0.303122 seconds and 5 git commands to generate.