implemented new code splitting mechanism (split to equal slices)
[deliverable/titan.core.git] / compiler2 / asn1 / AST_asn1.cc
CommitLineData
d44e3c4f 1/******************************************************************************
2 * Copyright (c) 2000-2016 Ericsson Telecom AB
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Eclipse Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/epl-v10.html
7 *
8 * Contributors:
9 * Baji, Laszlo
10 * Balasko, Jeno
11 * Baranyi, Botond
12 * Delic, Adam
13 * Kovacs, Ferenc
14 * Raduly, Csaba
15 * Szabados, Kristof
14e21cff 16 * Szabo, Bence Janos
d44e3c4f 17 * Szalai, Gabor
18 * Zalanyi, Balazs Andor
19 * Pandi, Krisztian
20 *
21 ******************************************************************************/
970ed795
EL
22#include "AST_asn1.hh"
23#include "../Identifier.hh"
24#include "../CompilerError.hh"
25#include "Block.hh"
26#include "TokenBuf.hh" // Ass_pard needs that
27#include "../Value.hh"
28#include "Object.hh"
29#include "../main.hh"
30#include "../CodeGenHelper.hh"
31#include "../../common/JSON_Tokenizer.hh"
7329404e 32#include "../DebuggerStuff.hh"
970ed795
EL
33
34/* defined in asn1p.y */
35extern int asn1_parse_string(const char* p_str);
36
37extern Common::Modules *modules; // in main.cc
38
39namespace Asn {
40
41 Module *Assignments::_spec_asss=0;
42 Assignments *parsed_assignments;
43
44 // =================================
45 // ===== Symbols
46 // =================================
47 Symbols::~Symbols()
48 {
49 for (size_t i = 0; i < syms_v.size(); i++) delete syms_v[i];
50 syms_v.clear();
51 syms_m.clear();
52 }
53
54 Symbols* Symbols::clone() const
55 {
56 FATAL_ERROR("Asn::Symbols::clone()");
57 return 0;
58 }
59
60 void Symbols::add_sym(Identifier *p_id)
61 {
62 if(!p_id)
63 FATAL_ERROR("NULL parameter: Asn::Symbols::add_sym()");
64 syms_v.add(p_id);
65 }
66
67 void Symbols::chk_uniq(const Location& p_loc)
68 {
69 for(size_t i=0; i<syms_v.size(); i++) {
70 Identifier *id = syms_v[i];
71 const string& name = id->get_name();
72 if (syms_m.has_key(name)) {
73 p_loc.error("Duplicate identifier in SymbolList: `%s'",
74 id->get_dispname().c_str());
75 } else syms_m.add(name, id);
76 }
77 }
78
79 // =================================
80 // ===== Exports
81 // =================================
82
83 Exports::Exports(bool p_expall)
84 : Node(), Location(), checked(false), my_mod(0), expall(p_expall),
85 symbols(expall ? 0 : new Symbols())
86 {}
87
88 Exports::Exports(Symbols *p_symlist)
89 : Node(), Location(), checked(false), my_mod(0), expall(false),
90 symbols(p_symlist ? p_symlist : new Symbols())
91 {}
92
93 Exports::~Exports()
94 {
95 delete symbols;
96 }
97
98 Exports* Exports::clone() const
99 {
100 FATAL_ERROR("Asn::Exports::clone()");
101 return 0;
102 }
103
104 bool Exports::exports_sym(const Identifier& p_id)
105 {
106 if(!checked) chk_exp();
107 if (expall) return true;
108 else return symbols->syms_m.has_key(p_id.get_name());
109 }
110
111 void Exports::chk_exp()
112 {
113 if(checked) return;
114 if(expall) return;
115 Ref_defd_simple *ref=0;
116 Error_Context cntxt(this, "In EXPORTS of module `%s'",
117 my_mod->get_modid().get_dispname().c_str());
118 symbols->chk_uniq(*this);
119 for(size_t i=0; i<symbols->syms_m.size(); i++) {
120 ref=new Ref_defd_simple(0, symbols->syms_m.get_nth_elem(i)->clone());
121 /* check whether exists or not */
122 my_mod->get_ass_bySRef(ref);
123 delete ref; ref=0;
124 }
125 checked=true;
126 }
127
128 // =================================
129 // ===== ImpMod
130 // =================================
131
132 ImpMod::ImpMod(Identifier *p_modid, Symbols *p_symlist)
133 : Node(), Location(), my_mod(0), modid(p_modid), mod(0)
134 {
135 if(!p_modid)
136 FATAL_ERROR("NULL parameter: Asn::ImpMod::ImpMod()");
137 set_fullname("<imports>."+modid->get_dispname());
138 symbols = p_symlist ? p_symlist : new Symbols();
139 }
140
141 ImpMod::~ImpMod()
142 {
143 delete modid;
144 delete symbols;
145 }
146
147 ImpMod* ImpMod::clone() const
148 {
149 FATAL_ERROR("Asn::ImpMod::clone()");
150 return 0;
151 }
152
153 bool ImpMod::has_sym(const Identifier& p_id) const
154 {
155 return symbols->syms_m.has_key(p_id.get_name());
156 }
157
158 void ImpMod::chk_imp(ReferenceChain& refch)
159 {
160 if(!my_mod)
161 FATAL_ERROR("Asn::ImpMod::chk_imp(): my_mod is NULL");
162 Common::Module *m=modules->get_mod_byId(*modid);
163 symbols->chk_uniq(*this);
164 vector<Common::Module> modules;
165 m->chk_imp(refch, modules);
166 modules.clear();
167 if(m->get_gen_code()) my_mod->set_gen_code();
168 for(size_t i=0; i<symbols->syms_m.size(); i++) {
169 const Identifier *id=symbols->syms_m.get_nth_elem(i);
170 Ref_defd_simple ref(0, new Identifier(*id));
171 ref.set_location(*this);
172 bool err=false;
173 if(!m->get_ass_bySRef(&ref)) err=true;
174 if(!err && !m->exports_sym(*id)) {
175 error("Symbol `%s' is not exported from module `%s'",
176 id->get_dispname().c_str(),
177 m->get_modid().get_dispname().c_str());
178 /* to avoid more error messages do not set err to true */
179 // err=true;
180 }
181 if(err) {
182 symbols->syms_m.erase(symbols->syms_m.get_nth_key(i));
183 // do not delete id; it is stored in the vector
184 i--;
185 }
186 }
187 }
188
189 void ImpMod::generate_code(output_struct *target)
190 {
191 const char *module_name = modid->get_name().c_str();
192
193 target->header.includes = mputprintf(target->header.includes,
194 "#include \"%s.hh\"\n",
195 duplicate_underscores ? module_name : modid->get_ttcnname().c_str());
196
197 target->functions.pre_init = mputprintf(target->functions.pre_init,
198 "%s%s.pre_init_module();\n", module_name,
199 "::module_object");
200 }
201
202 // =================================
203 // ===== Imports
204 // =================================
205
206 Imports::~Imports()
207 {
208 for(size_t i=0; i<impmods_v.size(); i++)
209 delete impmods_v[i];
210 impmods_v.clear();
211 impmods.clear();
212 impsyms_1.clear();
213 impsyms_m.clear();
214 }
215
216 Imports* Imports::clone() const
217 {
218 FATAL_ERROR("Asn::Imports::clone()");
219 return 0;
220 }
221
222 void Imports::add_impmod(ImpMod *p_impmod)
223 {
224 if(!p_impmod)
225 FATAL_ERROR("NULL parameter: Asn::Imports::add_impmod(): my_mod is NULL");
226 impmods_v.add(p_impmod);
227 p_impmod->set_my_mod(my_mod);
228 }
229
230 void Imports::set_my_mod(Module *p_mod)
231 {
232 my_mod=p_mod;
233 for(size_t i=0; i<impmods_v.size(); i++)
234 impmods_v[i]->set_my_mod(my_mod);
235 }
236
237 void Imports::chk_imp(ReferenceChain& refch)
238 {
239 if (checked) return;
240 checked = true;
241 if (impmods_v.size() <= 0) return;
242
243 if (!my_mod) FATAL_ERROR("Asn::Imports::chk_imp()");
244
245 for (size_t n = 0; n < impmods_v.size(); n++) {
246 ImpMod *im = impmods_v[n];
247 const Identifier& im_id = im->get_modid();
248 Error_Context cntxt(this, "In IMPORTS FROM `%s'",
249 im_id.get_dispname().c_str());
250 if (!modules->has_mod_withId(im_id)) {
251 im->error("There is no module with identifier `%s'",
252 im_id.get_dispname().c_str());
253 continue;
254 }
255 Common::Module *m = modules->get_mod_byId(im_id);
256 im->set_mod(m);
257 if (m->get_moduletype() != Module::MOD_ASN) {
258 im->error("An ASN.1 module cannot import from a TTCN-3 module");
259 continue;
260 }
261 else if (m == my_mod) {
262 im->error("A module cannot import from itself");
263 continue;
264 }
265 // check the imports recursively
266 refch.mark_state();
267 im->chk_imp(refch);
268 refch.prev_state();
269 // detect circular imports
270 if (!is_circular && m->is_visible(my_mod)) is_circular = true;
271 const string& im_name = im_id.get_name();
272 if (impmods.has_key(im_name)) {
273 const char *dispname_str = im_id.get_dispname().c_str();
274 im->error("Duplicate import from module `%s'", dispname_str);
275 impmods[im_name]->note("Previous import from `%s' is here",
276 dispname_str);
277 } else impmods.add(im_name, im);
278 Symbols *syms = im->symbols;
279 for (size_t i=0; i<syms->syms_m.size(); i++) {
280 const Identifier *id = syms->syms_m.get_nth_elem(i);
281 const string& key = id->get_name();
282 if(impsyms_1.has_key(key)) {
283 if(impsyms_1[key]!=m) {
284 impsyms_1.erase(key);
285 impsyms_m.add(key, 0);
286 }
287 }
288 else if(!impsyms_m.has_key(key)) {
289 impsyms_1.add(key, m);
290 }
291 }
292 }
293 }
294
295 bool Imports::has_impsym_withId(const Identifier& p_id) const
296 {
297 if (!checked) FATAL_ERROR("Imports::has_impsym_withId()");
298 const string& name = p_id.get_name();
299 return impsyms_1.has_key(name) || impsyms_m.has_key(name);
300 }
301
302 void Imports::get_imported_mods(Module::module_set_t& p_imported_mods)
303 {
304 for (size_t i = 0; i < impmods_v.size(); i++) {
305 Common::Module *m = impmods_v[i]->get_mod();
306 if (!m) continue;
307 if (!p_imported_mods.has_key(m)) {
308 p_imported_mods.add(m, 0);
309 m->get_visible_mods(p_imported_mods);
310 }
311 }
312 }
313
314 void Imports::generate_code(output_struct *target)
315 {
3f84031e 316 target->header.includes = mputstr(target->header.includes,
317 "#include <TTCN3.hh>\n");
970ed795
EL
318 for (size_t i = 0; i < impmods_v.size(); i++) {
319 ImpMod *im = impmods_v[i];
320 Common::Module *m = im->get_mod();
970ed795
EL
321 // inclusion of m's header file can be eliminated if we find another
322 // imported module that imports m
323 bool covered = false;
324 for (size_t j = 0; j < impmods_v.size(); j++) {
325 // skip over the same import definition
326 if (j == i) continue;
327 Common::Module *m2 = impmods_v[j]->get_mod();
328 // a module that is equivalent to the current module due to
329 // circular imports cannot be used to cover anything
330 if (m2->is_visible(my_mod)) continue;
331 if (m2->is_visible(m) && !m->is_visible(m2)) {
332 // m2 covers m (i.e. m is visible from m2)
333 // and they are not in the same import loop
334 covered = true;
335 break;
336 }
337 }
338 // do not generate the #include if a covering module is found
339 if (!covered) im->generate_code(target);
340 }
970ed795
EL
341 }
342
343 // =================================
344 // ===== Module
345 // =================================
346
347 Module::Module(Identifier *p_modid, TagDefault::tagdef_t p_tagdef,
348 bool p_extens_impl, Exports *p_exp, Imports *p_imp,
349 Assignments *p_asss)
350 : Common::Module(MOD_ASN, p_modid), tagdef(p_tagdef),
351 extens_impl(p_extens_impl), exp(p_exp), imp(p_imp), asss(p_asss)
352 {
353 if (!p_exp || !p_imp || !p_asss)
354 FATAL_ERROR("NULL parameter: Asn::Module::Module()");
355 if(!p_modid->isvalid_asn_modref()
356 && p_modid->get_dispname()!="<internal>")
357 error("`%s' is not a valid module identifier",
358 p_modid->get_dispname().c_str());
359 asss->set_parent_scope(this);
360 exp->set_my_mod(this);
361 imp->set_my_mod(this);
362 }
363
364 Module::~Module()
365 {
366 delete exp;
367 delete imp;
368 delete asss;
369 }
370
371 Module *Module::clone() const
372 {
373 FATAL_ERROR("Asn::Module::clone");
374 return 0;
375 }
376
377 Common::Assignment *Module::importAssignment(
378 const Identifier& p_source_modid, const Identifier& p_id) const
379 {
380 (void)p_source_modid;
381 if (asss->has_local_ass_withId(p_id)) {
382 return asss->get_local_ass_byId(p_id);
383 } else return 0;
384 }
385
386 void Module::set_fullname(const string& p_fullname)
387 {
388 Common::Module::set_fullname(p_fullname);
389 exp->set_fullname(p_fullname+".<exports>");
390 imp->set_fullname(p_fullname+".<imports>");
391 asss->set_fullname(p_fullname);
392 }
393
394 Common::Assignments *Module::get_scope_asss()
395 {
396 return asss;
397 }
398
399 bool Module::has_imported_ass_withId(const Identifier& p_id)
400 {
401 return imp->has_impsym_withId(p_id);
402 }
403
404 Common::Assignment* Module::get_ass_bySRef(Ref_simple *p_ref)
405 {
406 const Identifier *r_modid = p_ref->get_modid();
407 const Identifier *r_id = p_ref->get_id();
408
409 // return NULL if the reference is erroneous
410 if (!r_id) return 0;
411
412 Common::Module *r_mod=0;
413
414 if(!r_modid || *r_modid==*modid) {
415 if(asss->has_local_ass_withId(*r_id))
416 return asss->get_local_ass_byId(*r_id);
417 if(r_modid) {
418 p_ref->error("There is no assignment with name `%s'"
419 " in module `%s'", r_id->get_dispname().c_str(),
420 modid->get_dispname().c_str());
421 return 0;
422 }
423 if(imp->impsyms_1.has_key(r_id->get_name()))
424 r_mod=imp->impsyms_1[r_id->get_name()];
425 else if(imp->impsyms_m.has_key(r_id->get_name())) {
426 p_ref->error("There are more imported symbols with name `%s'"
427 " in module `%s'", r_id->get_dispname().c_str(),
428 modid->get_dispname().c_str());
429 return 0;
430 }
431 else {
432 p_ref->error("There is no assignment or imported symbol"
433 " with name `%s' in module `%s'",
434 r_id->get_dispname().c_str(),
435 modid->get_dispname().c_str());
436 return 0;
437 }
438 }
439 if(!r_mod) {
440 if(!imp->has_impmod_withId(*r_modid)) {
441 p_ref->error("There is no imported module with name `%s'",
442 r_modid->get_dispname().c_str());
443 return 0;
444 }
445 if(!imp->get_impmod_byId(*r_modid)->has_sym(*r_id)) {
446 p_ref->error("There is no symbol with name `%s'"
447 " imported from module `%s'",
448 r_id->get_dispname().c_str(),
449 r_modid->get_dispname().c_str());
450 return 0;
451 }
452 r_mod=modules->get_mod_byId(*r_modid);
453 }
454 Ref_defd_simple t_ref(0, r_id->clone());
455 return r_mod->get_ass_bySRef(&t_ref);
456 }
457
458 Assignments *Module::get_asss()
459 {
460 return asss;
461 }
462
463 bool Module::exports_sym(const Identifier& p_id)
464 {
465 return exp->exports_sym(p_id);
466 }
467
468 void Module::chk_imp(ReferenceChain& refch, vector<Common::Module>& /*moduleStack*/)
469 {
470 if (imp_checked) return;
471 const string& module_name = modid->get_dispname();
472 if (refch.exists(module_name)) {
473 // Do not warning for circular import in ASN.1 module. It is legal
474// warning("Circular import chain is not recommended: %s",
475// refch.get_dispstr(module_name).c_str());
476 return;
477 }
478 refch.add(module_name);
479 Error_Context backup;
480 Error_Context cntxt(this, "In ASN.1 module `%s'", module_name.c_str());
481 asss->chk_uniq();
482 imp->chk_imp(refch);
483 imp_checked = true;
484 collect_visible_mods();
485 }
486
487 void Module::chk()
488 {
489 DEBUG(1, "Checking ASN.1 module `%s'", modid->get_dispname().c_str());
490 Error_Context cntxt(this, "In ASN.1 module `%s'",
491 modid->get_dispname().c_str());
492 asss->chk_uniq();
493 exp->chk_exp();
494 asss->chk();
495 }
496
497 void Module::get_imported_mods(module_set_t& p_imported_mods)
498 {
499 imp->get_imported_mods(p_imported_mods);
500 }
501
502 bool Module::has_circular_import()
503 {
504 return imp->get_is_circular();
505 }
506
507 void Module::generate_code_internal(CodeGenHelper& cgh) {
508 imp->generate_code(cgh.get_current_outputstruct());
509 asss->generate_code(cgh);
510 }
511
512 void Module::dump(unsigned level) const
513 {
514 DEBUG(level, "ASN.1 module: %s", modid->get_dispname().c_str());
515 asss->dump(level + 1);
516 }
517
518 void Module::add_ass(Assignment *p_ass)
519 {
520 asss->add_ass(p_ass);
521 }
522
af710487 523 void Module::generate_json_schema(JSON_Tokenizer& json, map<Type*, JSON_Tokenizer>& json_refs)
970ed795
EL
524 {
525 // add a new property for this module
af710487 526 json.put_next_token(JSON_TOKEN_NAME, modid->get_ttcnname().c_str());
970ed795
EL
527
528 // add type definitions into an object
529 json.put_next_token(JSON_TOKEN_OBJECT_START);
530
af710487 531 // cycle through all type assignments, insert schema segments and references
532 // when needed
970ed795 533 for (size_t i = 0; i < asss->get_nof_asss(); ++i) {
7329404e
BB
534 Asn::Assignment* asn_ass = dynamic_cast<Asn::Assignment*>(asss->get_ass_byIndex(i));
535 if (asn_ass == NULL || asn_ass->get_ass_pard() != NULL) {
536 // skip parameterized types
537 continue;
538 }
539 if (Common::Assignment::A_TYPE == asn_ass->get_asstype()) {
540 Type* t = asn_ass->get_Type();
541 // skip instances of parameterized types
542 if (!t->is_pard_type_instance() && t->has_encoding(Type::CT_JSON)) {
543 // insert type's schema segment
544 t->generate_json_schema(json, false, false);
545
546 if (json_refs_for_all_types && !json_refs.has_key(t)) {
547 // create JSON schema reference for the type
548 JSON_Tokenizer* json_ref = new JSON_Tokenizer;
549 json_refs.add(t, json_ref);
550 t->generate_json_schema_ref(*json_ref);
af710487 551 }
970ed795
EL
552 }
553 }
554 }
555
556 // end of type definitions
557 json.put_next_token(JSON_TOKEN_OBJECT_END);
558 }
7329404e
BB
559
560 void Module::generate_debugger_init(output_struct *output)
561 {
562 // no debugging in ASN.1 modules
563 }
564
565 char* Module::generate_debugger_global_vars(char* str, Common::Module* current_mod)
566 {
567 for (size_t i = 0; i < asss->get_nof_asss(); ++i) {
568 Asn::Assignment* asn_ass = dynamic_cast<Asn::Assignment*>(asss->get_ass_byIndex(i));
569 if (asn_ass->get_ass_pard() != NULL) {
570 // this check must be done before get_asstype() is called
571 continue;
572 }
573 if (asn_ass->get_asstype() == Common::Assignment::A_CONST) {
574 str = generate_code_debugger_add_var(str, asn_ass, current_mod, "global");
575 }
576 }
577 return str;
578 }
579
580 void Module::generate_debugger_functions(output_struct *output)
581 {
f08ff9ca
BB
582 char* print_str = NULL;
583 char* overwrite_str = NULL;
7329404e
BB
584 for (size_t i = 0; i < asss->get_nof_asss(); ++i) {
585 Asn::Assignment* asn_ass = dynamic_cast<Asn::Assignment*>(asss->get_ass_byIndex(i));
586 if (asn_ass->get_ass_pard() != NULL) {
587 // skip parameterized types
588 // this check must be done before get_asstype() is called
589 continue;
590 }
591 if (Common::Assignment::A_TYPE == asn_ass->get_asstype()) {
592 Type* t = asn_ass->get_Type();
593 if (!t->is_pard_type_instance() && (t->is_structured_type() ||
594 t->get_typetype() == Type::T_ENUM_A ||
595 (t->is_ref() && t->get_type_refd()->is_pard_type_instance()))) {
596 // only structured types and enums are needed
597 // for instances of parameterized types, the last reference, which is
598 // not itself an instance of a parameterized type, holds the type's display name
f08ff9ca 599 print_str = mputprintf(print_str,
7329404e 600 " %sif (!strcmp(p_var.type_name, \"%s\")) {\n"
f08ff9ca 601 " ((const %s*)ptr)->log();\n"
7329404e
BB
602 " }\n"
603 " else if (!strcmp(p_var.type_name, \"%s template\")) {\n"
f08ff9ca 604 " ((const %s_template*)ptr)->log();\n"
7329404e 605 " }\n"
f08ff9ca
BB
606 , (print_str != NULL) ? "else " : ""
607 , t->get_dispname().c_str(), t->get_genname_value(this).c_str()
608 , t->get_dispname().c_str(), t->get_genname_value(this).c_str());
609 overwrite_str = mputprintf(overwrite_str,
610 " %sif (!strcmp(p_var.type_name, \"%s\")) {\n"
611 " ((%s*)p_var.value)->set_param(p_new_value);\n"
612 " }\n"
613 " else if (!strcmp(p_var.type_name, \"%s template\")) {\n"
614 " ((%s_template*)p_var.value)->set_param(p_new_value);\n"
615 " }\n"
616 , (overwrite_str != NULL) ? "else " : ""
7329404e
BB
617 , t->get_dispname().c_str(), t->get_genname_value(this).c_str()
618 , t->get_dispname().c_str(), t->get_genname_value(this).c_str());
619 }
620 }
621 }
f08ff9ca 622 if (print_str != NULL) {
7329404e
BB
623 // don't generate an empty printing function
624 output->header.class_defs = mputprintf(output->header.class_defs,
f08ff9ca
BB
625 "/* Debugger printing and overwriting functions for types declared in this module */\n\n"
626 "extern CHARSTRING print_var_%s(const TTCN3_Debugger::variable_t& p_var);\n"
627 "extern boolean set_var_%s(TTCN3_Debugger::variable_t& p_var, Module_Param& p_new_value);\n",
628 get_modid().get_ttcnname().c_str(), get_modid().get_ttcnname().c_str());
7329404e
BB
629 output->source.global_vars = mputprintf(output->source.global_vars,
630 "\n/* Debugger printing function for types declared in this module */\n"
631 "CHARSTRING print_var_%s(const TTCN3_Debugger::variable_t& p_var)\n"
632 "{\n"
f08ff9ca 633 " const void* ptr = p_var.set_function != NULL ? p_var.value : p_var.cvalue;\n"
7329404e
BB
634 " TTCN_Logger::begin_event_log2str();\n"
635 "%s"
636 " else {\n"
637 " TTCN_Logger::log_event_str(\"<unrecognized value or template>\");\n"
638 " }\n"
639 " return TTCN_Logger::end_event_log2str();\n"
f08ff9ca
BB
640 "}\n\n"
641 "/* Debugger overwriting function for types declared in this module */\n"
642 "boolean set_var_%s(TTCN3_Debugger::variable_t& p_var, Module_Param& p_new_value)\n"
643 "{\n"
644 "%s"
645 " else {\n"
646 " return FALSE;\n"
647 " }\n"
648 " return TRUE;\n"
649 "}\n", get_modid().get_ttcnname().c_str(), print_str,
650 get_modid().get_ttcnname().c_str(), overwrite_str);
b076ae5d
BB
651 Free(print_str);
652 Free(overwrite_str);
7329404e
BB
653 }
654 }
970ed795
EL
655
656 // =================================
657 // ===== Assignments
658 // =================================
659
660 Assignments::Assignments(const Assignments& p)
661 : Common::Assignments(p), checked(false)
662 {
663 for(size_t i = 0; i < p.asss_v.size(); i++)
664 add_ass(p.asss_v[i]->clone());
665 }
666
667 Assignments::~Assignments()
668 {
669 for (size_t i = 0; i < asss_v.size(); i++) delete asss_v[i];
670 asss_v.clear();
671 asss_m.clear();
672 }
673
674 Assignments *Assignments::clone() const
675 {
676 return new Assignments(*this);
677 }
678
679 void Assignments::set_fullname(const string& p_fullname)
680 {
681 Common::Assignments::set_fullname(p_fullname);
682 string s(p_fullname);
683 if (s != "@") s += '.';
684 for (size_t i = 0; i < asss_v.size(); i++) {
685 Assignment *ass = asss_v[i];
686 ass->set_fullname(s+ass->get_id().get_dispname());
687 }
688 }
689
690 bool Assignments::has_local_ass_withId(const Identifier& p_id)
691 {
692 if (!checked) chk_uniq();
693 if (asss_m.has_key(p_id.get_name())) return true;
694 Assignments *spec_asss = _spec_asss->get_asss();
695 if (spec_asss != this) return spec_asss->has_ass_withId(p_id);
696 else return false;
697 }
698
699 Assignment* Assignments::get_local_ass_byId(const Identifier& p_id)
700 {
701 if (!checked) chk_uniq();
702 const string& name = p_id.get_name();
703 if (asss_m.has_key(name)) return asss_m[name];
704 Assignments *spec_asss = _spec_asss->get_asss();
705 if (spec_asss != this) return spec_asss->get_local_ass_byId(p_id);
706 else return 0;
707 }
708
709 size_t Assignments::get_nof_asss()
710 {
711 if (!checked) chk_uniq();
712 return asss_m.size();
713 }
714
715 Common::Assignment* Assignments::get_ass_byIndex(size_t p_i)
716 {
717 if (!checked) chk_uniq();
718 return asss_m.get_nth_elem(p_i);
719 }
720
721 void Assignments::add_ass(Assignment *p_ass)
722 {
723 if (!p_ass) FATAL_ERROR("Asn::Assignments::add_ass()");
724 asss_v.add(p_ass);
725 p_ass->set_my_scope(this);
726 if(checked) {
727 const Identifier& id = p_ass->get_id();
728 const string& name = id.get_name();
729 if(asss_m.has_key(name)) {
730 const char *dispname_str = id.get_dispname().c_str();
731 p_ass->error("Duplicate assignment with identifier `%s'", dispname_str);
732 asss_m[name]->note("Previous assignment with identifier `%s' is here",
733 dispname_str);
734 } else asss_m.add(name, p_ass);
735 }
736 }
737
738 void Assignments::chk()
739 {
740 for(size_t i = 0; i < asss_v.size(); i++) asss_v[i]->chk();
741 }
742
743 void Assignments::chk_uniq()
744 {
745 if (checked) return;
746 asss_m.clear();
747 Assignments *spec_asss = _spec_asss->get_asss();
748 for(size_t i = 0; i < asss_v.size(); i++) {
749 Assignment *ass = asss_v[i];
750 const Identifier& id = ass->get_id();
751 const string& name = id.get_name();
752 if (this != spec_asss && spec_asss->has_ass_withId(id)) {
753 ass->error("`%s' is a reserved identifier", id.get_dispname().c_str());
754 } else if (asss_m.has_key(name)) {
755 const char *dispname_str = id.get_dispname().c_str();
756 ass->error("Duplicate assignment with identifier `%s'", dispname_str);
757 asss_m[name]->note("Previous assignment with identifier `%s' is here",
758 dispname_str);
759 } else asss_m.add(name, ass);
760 }
761 checked = true;
762 }
763
764 void Assignments::set_right_scope(Scope *p_scope)
765 {
766 for(size_t i = 0; i < asss_v.size(); i++)
767 asss_v[i]->set_right_scope(p_scope);
768 }
769
770 void Assignments::create_spec_asss()
771 {
772 if (_spec_asss)
773 FATAL_ERROR("Assignments::create_spec_asss(): duplicate initialization");
774
775 const char *s_asss = "$#&&&(#TITAN$#&&^#% Assignments\n"
776 "$#&&&(#TITAN$#&&^#% UpperIdentifier\"EXTERNAL\""
777 " ::= [UNIVERSAL 8] IMPLICIT SEQUENCE {\n"
778 " identification CHOICE {\n"
779 " syntaxes SEQUENCE {\n"
780 " abstract OBJECT IDENTIFIER,\n"
781 " transfer OBJECT IDENTIFIER\n"
782 " },\n"
783 " syntax OBJECT IDENTIFIER,\n"
784 " presentation-context-id INTEGER,\n"
785 " context-negotiation SEQUENCE {\n"
786 " presentation-context-id INTEGER,\n"
787 " transfer-syntax OBJECT IDENTIFIER\n"
788 " },\n"
789 " transfer-syntax OBJECT IDENTIFIER,\n"
790 " fixed NULL\n"
791 " },\n"
792 " data-value-descriptor ObjectDescriptor OPTIONAL,\n"
793 " data-value OCTET STRING\n"
794 "} (WITH COMPONENTS {\n"
795 " ...,\n"
796 " identification (WITH COMPONENTS {\n"
797 " ...,\n"
798 " syntaxes ABSENT,\n"
799 " transfer-syntax ABSENT,\n"
800 " fixed ABSENT\n"
801 " })\n"
802 "})\n"
803
804 "$#&&&(#TITAN$#&&^#% UpperIdentifier\"EMBEDDED PDV\""
805 " ::= [UNIVERSAL 11] IMPLICIT SEQUENCE {\n"
806 " identification CHOICE {\n"
807 " syntaxes SEQUENCE {\n"
808 " abstract OBJECT IDENTIFIER,\n"
809 " transfer OBJECT IDENTIFIER\n"
810 " },\n"
811 " syntax OBJECT IDENTIFIER,\n"
812 " presentation-context-id INTEGER,\n"
813 " context-negotiation SEQUENCE {\n"
814 " presentation-context-id INTEGER,\n"
815 " transfer-syntax OBJECT IDENTIFIER\n"
816 " },\n"
817 " transfer-syntax OBJECT IDENTIFIER,\n"
818 " fixed NULL\n"
819 " },\n"
820 " data-value-descriptor ObjectDescriptor OPTIONAL,\n"
821 " data-value OCTET STRING\n"
822 "} (WITH COMPONENTS {\n"
823 " ...,\n"
824 " data-value-descriptor ABSENT\n"
825 "})\n"
826
827 "$#&&&(#TITAN$#&&^#% UpperIdentifier\"CHARACTER STRING\""
828 " ::= [UNIVERSAL 29] IMPLICIT SEQUENCE {\n"
829 " identification CHOICE {\n"
830 " syntaxes SEQUENCE {\n"
831 " abstract OBJECT IDENTIFIER,\n"
832 " transfer OBJECT IDENTIFIER\n"
833 " },\n"
834 " syntax OBJECT IDENTIFIER,\n"
835 " presentation-context-id INTEGER,\n"
836 " context-negotiation SEQUENCE {\n"
837 " presentation-context-id INTEGER,\n"
838 " transfer-syntax OBJECT IDENTIFIER\n"
839 " },\n"
840 " transfer-syntax OBJECT IDENTIFIER,\n"
841 " fixed NULL\n"
842 " },\n"
843 " data-value-descriptor ObjectDescriptor OPTIONAL,\n"
844 " string-value OCTET STRING\n"
845 "} (WITH COMPONENTS {\n"
846 " ...,\n"
847 " data-value-descriptor ABSENT\n"
848 "})\n"
849
850 "$#&&&(#TITAN$#&&^#% UpperIdentifier\"REAL\""
851 " ::= [UNIVERSAL 9] IMPLICIT SEQUENCE {\n"
852 " mantissa INTEGER,\n"
853 " base INTEGER (2|10),\n"
854 " exponent INTEGER\n"
855 "}\n"
856
857 "$#&&&(#TITAN$#&&^#% UpperIdentifier\"TYPE-IDENTIFIER\"\n"
858 "::= CLASS\n"
859 "{\n"
860 " &id OBJECT IDENTIFIER UNIQUE,\n"
861 " &Type\n"
862 "}\n"
863 "WITH SYNTAX {\n"
864 " &Type IDENTIFIED BY &id\n"
865 "}\n"
866
867 "$#&&&(#TITAN$#&&^#% UpperIdentifier\"ABSTRACT-SYNTAX\""
868 " ::= CLASS {\n"
869 " &id OBJECT IDENTIFIER UNIQUE,\n"
870 " &Type,\n"
871 " &property BIT STRING {handles-invalid-encodings(0)} DEFAULT {}\n"
872 "}\n"
873 "WITH SYNTAX {\n"
874 " &Type IDENTIFIED BY &id [HAS PROPERTY &property]\n"
875 "}\n"
876 ;
877
878 if(asn1_parse_string(s_asss) || !parsed_assignments)
879 FATAL_ERROR("special assignments");
880 _spec_asss=new Module
881 (new Identifier(Identifier::ID_ASN, string("<internal>")),
882 TagDefault::AUTOMATIC, false, new Exports(true), new Imports(),
883 parsed_assignments);
884 _spec_asss->set_location("<internal>");
885 _spec_asss->set_scope_name(_spec_asss->get_modid().get_dispname());
886
887 parsed_assignments->set_fullname(string('@'));
888 _spec_asss->chk();
889
890 /*
891 // this is used to generate the files which are then
892 // included/copied/edited in core library
893 _spec_asss->set_gen_code();
894 _spec_asss->generate_code();
895 */
896 }
897
898 void Assignments::destroy_spec_asss()
899 {
900 if (!_spec_asss)
901 FATAL_ERROR("Assignments::destroy_spec_asss(): duplicate cleanup");
902
903 delete _spec_asss;
904 _spec_asss = 0;
905 }
906
907 bool Assignments::is_spec_asss(Common::Module *p_mod)
908 {
909 if (!p_mod) FATAL_ERROR("Assignments::is_spec_asss()");
910 if (_spec_asss) return p_mod == static_cast<Common::Module*>(_spec_asss);
911 else return false;
912 }
913
914 void Assignments::generate_code(output_struct* target)
915 {
916 for (size_t i = 0; i < asss_v.size(); i++) {
917 Assignment *ass = asss_v[i];
918 if (!top_level_pdu || ass->get_checked()) ass->generate_code(target);
919 }
920 }
921
922 void Assignments::generate_code(CodeGenHelper& cgh) {
923 for (size_t i = 0; i < asss_v.size(); i++) {
924 Assignment *ass = asss_v[i];
14e21cff 925 if (!top_level_pdu || ass->get_checked()) {
926 ass->generate_code(cgh);
927 CodeGenHelper::update_intervals(cgh.get_current_outputstruct());
928 }
970ed795
EL
929 }
930 }
931
932 void Assignments::dump(unsigned level) const
933 {
934 DEBUG(level, "Assignments (%lu pcs.)", (unsigned long) asss_v.size());
935 for(size_t i = 0; i < asss_v.size(); i++) asss_v[i]->dump(level + 1);
936 }
937
938 // =================================
939 // ===== Ass_pard
940 // =================================
941
942 Ass_pard::Ass_pard(Block *p_parlist_block)
943 : Common::Node(), parlist_block(p_parlist_block)
944 {
945 if(!p_parlist_block)
946 FATAL_ERROR("NULL parameter: Asn::Ass_pard::Ass_pard()");
947 }
948
949 Ass_pard::Ass_pard(const Ass_pard& p)
950 : Common::Node(p)
951 {
952 parlist_block=p.parlist_block?p.parlist_block->clone():0;
953 for(size_t i=0; i<p.dummyrefs.size(); i++)
954 dummyrefs.add(p.dummyrefs[i]->clone());
955 for(size_t i=0; i<p.governors.size(); i++)
956 governors.add(p.governors[i]->clone());
957 }
958
959 Ass_pard::~Ass_pard()
960 {
961 delete parlist_block;
962 for (size_t i = 0; i < dummyrefs.size(); i++) delete dummyrefs[i];
963 dummyrefs.clear();
964 for (size_t i = 0; i < governors.size(); i++) delete governors[i];
965 governors.clear();
966 for (size_t i = 0; i < inst_cnts.size(); i++)
967 delete inst_cnts.get_nth_elem(i);
968 inst_cnts.clear();
969 }
970
971 void Ass_pard::preparse_pars()
972 {
973 if(!parlist_block) return;
974 Error_Context cntxt
975 (my_ass, "While checking formal parameters of parameterized"
976 " assignment `%s'", my_ass->get_fullname().c_str());
977 TokenBuf *parlist_tb=parlist_block->get_TokenBuf();
978 enum state_type {S_START, S_GOV, S_DUMMYREF, S_COMMA, S_RDY, S_ERR};
979 TokenBuf *gov_tb=0;
980 for(state_type st=S_START; st!=S_RDY; ) {
981 switch(st) {
982 case S_START:
983 gov_tb=new TokenBuf();
984 switch(parlist_tb->get_at(1)->get_token()) {
985 case ',':
986 case '\0': // EOF
987 st=S_DUMMYREF;
988 break;
989 default:
990 st=S_GOV;
991 } // switch
992 break; // S_START
993 case S_GOV: {
994 Token *token=parlist_tb->pop_front_token();
995 switch(token->get_token()) {
996 case ',':
997 case '\0': // EOF
998 token->error("Syntax error, premature end of parameter"
999 " (missing `:')");
1000 delete token;
1001 st=S_ERR;
1002 break;
1003 case ':':
1004 delete token;
1005 st=S_DUMMYREF;
1006 break;
1007 default:
1008 gov_tb->push_back_token(token);
1009 } // switch token
1010 break;} // S_GOV
1011 case S_DUMMYREF: {
1012 Token *token=parlist_tb->pop_front_token();
1013 switch(token->get_token()) {
1014 case TOK_UpperIdentifier:
1015 case TOK_LowerIdentifier:
1016 dummyrefs.add(token->get_semval_id().clone());
1017 gov_tb->push_front_token(token);
1018 gov_tb->push_back_kw_token(TOK_Assignment);
1019 governors.add(gov_tb);
1020 gov_tb=0;
1021 st=S_COMMA;
1022 break;
1023 case ',':
1024 case '\0': // EOF
1025 default:
1026 token->error("Syntax error, DummyReference was expected");
1027 delete token;
1028 st=S_ERR;
1029 } // switch token
1030 break;} // S_DUMMYREF
1031 case S_COMMA: {
1032 Token *token=parlist_tb->pop_front_token();
1033 switch(token->get_token()) {
1034 case ',':
1035 st=S_START;
1036 break;
1037 case '\0': // EOF
1038 st=S_RDY;
1039 break;
1040 default:
1041 token->error("Syntax error, `,' was expected");
1042 st=S_ERR;
1043 } // switch token
1044 delete token;
1045 break;} // S_COMMA
1046 case S_ERR:
1047 delete gov_tb;
1048 for (size_t i = 0; i < dummyrefs.size(); i++) delete dummyrefs[i];
1049 dummyrefs.clear();
1050 for (size_t i = 0; i < governors.size(); i++) delete governors[i];
1051 governors.clear();
1052 st=S_RDY;
1053 break; // S_ERR
1054 case S_RDY:
1055 default:
1056 FATAL_ERROR("Ass_pard::preparse_pars()");
1057 } // switch st
1058 } // for st
1059 delete parlist_block;
1060 parlist_block=0;
1061 }
1062
1063 size_t Ass_pard::get_nof_pars()
1064 {
1065 if (parlist_block) preparse_pars();
1066 return dummyrefs.size();
1067 }
1068
1069 const Identifier& Ass_pard::get_nth_dummyref(size_t i)
1070 {
1071 if (parlist_block) preparse_pars();
1072 return *(dummyrefs[i]);
1073 }
1074
1075 TokenBuf* Ass_pard::clone_nth_governor(size_t i)
1076 {
1077 if (parlist_block) preparse_pars();
1078 return governors[i]->clone();
1079 }
1080
1081 size_t Ass_pard::new_instnum(Common::Module *p_mod)
1082 {
1083 if (!p_mod) FATAL_ERROR("Ass_pard::new_instnum()");
1084 if (inst_cnts.has_key(p_mod)) return ++(*inst_cnts[p_mod]);
1085 else {
1086 inst_cnts.add(p_mod, new size_t(1));
1087 return 1;
1088 }
1089 }
1090
1091 // =================================
1092 // ===== Assignment
1093 // =================================
1094
1095 Assignment::Assignment(const Assignment& p)
1096 : Common::Assignment(p), dontgen(false)
1097 {
1098 if(p.ass_pard) {
1099 ass_pard=p.ass_pard->clone();
1100 ass_pard->set_my_ass(this);
1101 }
1102 else ass_pard=0;
1103 }
1104
1105 string Assignment::get_genname() const
1106 {
1107 if (!my_scope ||
1108 my_scope->get_parent_scope() == my_scope->get_scope_mod()) {
1109 // use the simple identifier if the assignment does not have scope
1110 // or it is a simple assignment at module scope
1111 return id->get_name();
1112 } else {
1113 // this assignment belongs to an instantiation of a parameterized
1114 // assignment: use the name of the parent scope to obtain genname
1115 string genname_asn("@");
1116 genname_asn += my_scope->get_scope_name();
1117 const string& id_dispname = id->get_dispname();
1118 bool is_parass = id_dispname.find('.') == id_dispname.size();
1119 if (is_parass) {
1120 // the assignment has a normal identifier:
1121 // it represents a formal parameter -> actual parameter binding
1122 // the id (which is the dummy reference) must be used to get a
1123 // unique genname
1124 genname_asn += '.';
1125 genname_asn += id_dispname;
1126 }
1127 // otherwise the assignment represents an instance of the parameterized
1128 // assignment itself: the scope name can be used alone as genname
1129 string ret_val(Identifier::asn_2_name(genname_asn));
1130 // in case of parameter assignments a suffix is appended to avoid name
1131 // clash with the embedded settings of the same instantiation
1132 if (is_parass) ret_val += "_par_";
1133 return ret_val;
1134 }
1135 }
1136
1137 Assignment* Assignment::new_instance0()
1138 {
1139 // Classes derived from Assignment must implement new_instance0.
1140 // See Asn::Ass_*::new_instance0
1141 FATAL_ERROR("Asn::Assignment::new_instance0()");
1142 return 0;
1143 }
1144
1145 Assignment::Assignment(asstype_t p_asstype, Identifier *p_id,
1146 Ass_pard *p_ass_pard)
1147 : Common::Assignment(p_asstype, p_id),
1148 ass_pard(p_ass_pard), dontgen(false)
1149 {
1150 if(ass_pard) ass_pard->set_my_ass(this);
1151 }
1152
1153 Assignment::~Assignment()
1154 {
1155 delete ass_pard;
1156 }
1157
1158 bool Assignment::is_asstype(asstype_t p_asstype, ReferenceChain* refch)
1159 {
1160 bool destroy_refch=false;
1161 if(!refch) {
1162 refch=new ReferenceChain(this, "While examining kind of assignment");
1163 destroy_refch=true;
1164 } else refch->mark_state();
1165 bool b=(p_asstype==asstype);
1166 if(!refch->add(get_fullname())) b=p_asstype==A_ERROR;
1167 if(destroy_refch) delete refch;
1168 else refch->prev_state();
1169 return b;
1170 }
1171
1172 Assignment* Assignment::new_instance(Common::Module *p_mod)
1173 {
1174 if(!ass_pard) {
1175 error("`%s' is not a parameterized assignment",
1176 get_fullname().c_str());
1177 return 0;
1178 }
1179 Assignment *new_ass=new_instance0();
1180 delete new_ass->id; // it was just a temporary, containing "<error>"
1181 string new_name(id->get_asnname());
1182 new_name += '.';
1183 new_name += p_mod->get_modid().get_asnname();
1184 new_name += ".inst";
1185 new_name += Int2string(ass_pard->new_instnum(p_mod));
1186 new_ass->id=new Identifier(Identifier::ID_ASN, new_name);
1187 return new_ass;
1188 }
1189
1190 Type* Assignment::get_Type()
1191 {
1192 error("`%s' is not a type assignment", get_fullname().c_str());
1193 return 0;
1194 }
1195
1196 Value* Assignment::get_Value()
1197 {
1198 error("`%s' is not a value assignment", get_fullname().c_str());
1199 return 0;
1200 }
1201
1202 ValueSet* Assignment::get_ValueSet()
1203 {
1204 error("`%s' is not a valueset assignment", get_fullname().c_str());
1205 return 0;
1206 }
1207
1208 ObjectClass* Assignment::get_ObjectClass()
1209 {
1210 error("`%s' is not a objectclass assignment", get_fullname().c_str());
1211 return 0;
1212 }
1213
1214 Object* Assignment::get_Object()
1215 {
1216 error("`%s' is not a object assignment", get_fullname().c_str());
1217 return 0;
1218 }
1219
1220 ObjectSet* Assignment::get_ObjectSet()
1221 {
1222 error("`%s' is not a objectset assignment", get_fullname().c_str());
1223 return 0;
1224 }
1225
1226 void Assignment::chk()
1227 {
1228 if(ass_pard) {
1229 ass_pard->get_nof_pars();
1230 checked=true;
1231 return;
1232 }
1233 DEBUG(7, "`%s' assignment not checked.", get_fullname().c_str());
1234 }
1235
1236 void Assignment::dump(unsigned level) const
1237 {
1238 DEBUG(level, "Assignment(%d): %s%s", get_asstype(),
1239 id->get_dispname().c_str(), ass_pard?"{}":"");
1240 }
1241
1242 // =================================
1243 // ===== Ass_Undef
1244 // =================================
1245
1246 Ass_Undef::Ass_Undef(Identifier *p_id, Ass_pard *p_ass_pard,
1247 Node *p_left, Node *p_right)
1248 : Assignment(A_UNDEF, p_id, p_ass_pard),
1249 left(p_left), right(p_right), right_scope(0), ass(0)
1250 {
1251 if(!p_right)
1252 FATAL_ERROR("NULL parameter: Asn::Ass_Undef::Ass_Undef()");
1253 }
1254
1255 Ass_Undef::Ass_Undef(const Ass_Undef& p)
1256 : Assignment(p), right_scope(0)
1257 {
1258 left=p.left?p.left->clone():0;
1259 right=p.right?p.right->clone():0;
1260 ass=p.ass?p.ass->clone():0;
1261 }
1262
1263 Ass_Undef::~Ass_Undef()
1264 {
1265 delete left;
1266 delete right;
1267 delete ass;
1268 }
1269
1270 Assignment* Ass_Undef::clone() const
1271 {
1272 if(ass) return ass->clone();
1273 else return new Ass_Undef(*this);
1274 }
1275
1276 Assignment* Ass_Undef::new_instance0()
1277 {
1278 if(ass) FATAL_ERROR("Asn::Ass_Undef::new_instance0()");
1279 return new Ass_Undef
1280 (new Identifier(Identifier::ID_ASN, string("<error>")),
1281 0, left?left->clone():0, right->clone());
1282 }
1283
1284 Assignment::asstype_t Ass_Undef::get_asstype() const
1285 {
1286 const_cast<Ass_Undef*>(this)->classify_ass();
1287 return asstype;
1288 }
1289
1290 void Ass_Undef::set_fullname(const string& p_fullname)
1291 {
1292 Assignment::set_fullname(p_fullname);
1293 if (left) left->set_fullname(p_fullname);
1294 if (right) right->set_fullname(p_fullname);
1295 if (ass) ass->set_fullname(p_fullname);
1296 }
1297
1298 void Ass_Undef::set_my_scope(Scope *p_scope)
1299 {
1300 Assignment::set_my_scope(p_scope);
1301 if(ass) ass->set_my_scope(p_scope);
1302 right_scope=p_scope;
1303 }
1304
1305 void Ass_Undef::set_right_scope(Scope *p_scope)
1306 {
1307 if(ass) ass->set_right_scope(p_scope);
1308 right_scope=p_scope;
1309 }
1310
1311 bool Ass_Undef::is_asstype(asstype_t p_asstype, ReferenceChain* refch)
1312 {
1313 classify_ass(refch);
1314 return asstype != A_ERROR ? ass->is_asstype(p_asstype, refch) : false;
1315 }
af710487 1316
1317 Ass_pard* Ass_Undef::get_ass_pard() const
1318 {
1319 if (NULL != ass) {
1320 return ass->get_ass_pard();
1321 }
1322 return ass_pard;
1323 }
970ed795
EL
1324
1325 bool Ass_Undef::_error_if_pard()
1326 {
1327 if(ass_pard) {
1328 error("`%s' is a parameterized assignment", get_fullname().c_str());
1329 return true;
1330 }
1331 return false;
1332 }
1333
1334 Setting* Ass_Undef::get_Setting()
1335 {
1336 if(_error_if_pard()) return 0;
1337 if(!checked) chk();
1338 return ass->get_Setting();
1339 }
1340
1341 Type* Ass_Undef::get_Type()
1342 {
1343 if(_error_if_pard()) return 0;
1344 if(!checked) chk();
1345 return ass->get_Type();
1346 }
1347
1348 Value* Ass_Undef::get_Value()
1349 {
1350 if(_error_if_pard()) return 0;
1351 if(!checked) chk();
1352 return ass->get_Value();
1353 }
1354
1355 ValueSet* Ass_Undef::get_ValueSet()
1356 {
1357 if(_error_if_pard()) return 0;
1358 if(!checked) chk();
1359 return ass->get_ValueSet();
1360 }
1361
1362 ObjectClass* Ass_Undef::get_ObjectClass()
1363 {
1364 if(_error_if_pard()) return 0;
1365 if(!checked) chk();
1366 return ass->get_ObjectClass();
1367 }
1368
1369 Object* Ass_Undef::get_Object()
1370 {
1371 if(_error_if_pard()) return 0;
1372 if(!checked) chk();
1373 return ass->get_Object();
1374 }
1375
1376 ObjectSet* Ass_Undef::get_ObjectSet()
1377 {
1378 if(_error_if_pard()) return 0;
1379 if(!checked) chk();
1380 return ass->get_ObjectSet();
1381 }
1382
1383 void Ass_Undef::chk()
1384 {
1385 if(checked) return;
1386 if(ass_pard) {
1387 ass_pard->get_nof_pars();
1388 checked=true;
1389 return;
1390 }
1391 classify_ass();
1392 ass->chk();
1393 checked=true;
1394 }
1395
1396 void Ass_Undef::generate_code(output_struct *target, bool)
1397 {
1398 if (ass_pard || dontgen) return;
1399 classify_ass();
1400 ass->generate_code(target);
1401 }
1402
1403 void Ass_Undef::generate_code(CodeGenHelper& cgh) {
1404 if (ass_pard || dontgen) return;
1405 classify_ass();
1406 ass->generate_code(cgh);
14e21cff 1407 CodeGenHelper::update_intervals(cgh.get_current_outputstruct());
970ed795
EL
1408 }
1409
1410 void Ass_Undef::dump(unsigned level) const
1411 {
1412 if(ass)
1413 ass->dump(level);
1414 else {
1415 DEBUG(level, "Undef assignment: %s%s",
1416 id->get_dispname().c_str(), ass_pard?"{}":"");
1417 }
1418 }
1419
1420 void Ass_Undef::classify_ass(ReferenceChain *refch)
1421 {
1422 if(asstype!=A_UNDEF) return;
1423 bool destroy_refch=false;
1424 if(!refch) {
1425 refch=new ReferenceChain(this, "While examining kind of assignment");
1426 destroy_refch=true;
1427 } else refch->mark_state();
1428
1429 Error_Context ec_backup(1);
1430 Error_Context cntxt(this, "In assignment `%s'",
1431 id->get_dispname().c_str());
1432
1433 /* temporary pointers */
1434 Reference *t_ref=0;
1435 Reference *t_ref2=0;
1436 Block *t_block=0;
1437
1438 if(!refch->add(get_fullname()))
1439 goto error;
1440 if((t_ref=dynamic_cast<Reference*>(left))) {
1441 t_ref->set_my_scope(my_scope);
1442 if(t_ref->refers_to_st(Setting::S_ERROR, refch))
1443 goto error;
1444 }
1445 if((t_ref=dynamic_cast<Reference*>(right))) {
1446 t_ref->set_my_scope(right_scope);
1447 /*
1448 if(t_ref->refers_to_st(Setting::S_ERROR, refch))
1449 t_ref->error("Cannot recognize assignment `%s'",
1450 t_ref->get_dispname().c_str());
1451 */
1452 }
1453
1454 if(id->isvalid_asn_objclassref()
1455 && !left
1456 && (t_ref=dynamic_cast<Ref_defd*>(right))
1457 && t_ref->refers_to_st(Setting::S_OC, refch)
1458 ) {
1459 ass=new Ass_OC(id->clone(), ass_pard, new OC_refd(t_ref));
1460 ass_pard=0;
1461 right=0;
1462 asstype=A_OC;
1463 }
1464 else if(id->isvalid_asn_typeref()
1465 && !left
1466 && (t_ref=dynamic_cast<Ref_defd*>(right))
1467 && (t_ref->refers_to_st(Setting::S_T, refch)
1468 || t_ref->refers_to_st(Setting::S_VS, refch))
1469 ) {
1470 Type *t_type=new Type(Type::T_REFD, t_ref);
1471 t_type->set_location(*t_ref);
1472 ass=new Ass_T(id->clone(), ass_pard, t_type);
1473 ass_pard=0;
1474 right=0;
1475 asstype=A_TYPE;
1476 }
1477 else if(id->isvalid_asn_objsetref()
1478 && (t_ref=dynamic_cast<Ref_simple*>(left))
1479 && (t_block=dynamic_cast<Block*>(right))
1480 && t_ref->refers_to_st(Setting::S_OC, refch)
1481 ) {
1482 ass=new Ass_OS(id->clone(), ass_pard,
1483 new OC_refd(t_ref), new OS_defn(t_block));
1484 ass_pard=0;
1485 left=0;
1486 right=0;
1487 asstype=A_OS;
1488 }
1489 else if(id->isvalid_asn_valsetref()
1490 && (t_ref=dynamic_cast<Ref_simple*>(left))
1491 && (t_block=dynamic_cast<Block*>(right))
1492 && (t_ref->refers_to_st(Setting::S_T, refch)
1493 || t_ref->refers_to_st(Setting::S_VS, refch))
1494 ) {
1495 Type *t_type=new Type(Type::T_REFD, t_ref);
1496 t_type->set_location(*t_ref);
1497 ass=new Ass_VS(id->clone(), ass_pard, t_type, t_block);
1498 ass_pard=0;
1499 left=0;
1500 right=0;
1501 asstype=A_VS;
1502 }
1503 else if(id->isvalid_asn_objref()
1504 && (t_ref=dynamic_cast<Ref_simple*>(left))
1505 && ((t_block=dynamic_cast<Block*>(right))
1506 || (t_ref2=dynamic_cast<Reference*>(right)))
1507 && t_ref->refers_to_st(Setting::S_OC, refch)
1508 ) {
1509 OC_refd *t_oc=new OC_refd(t_ref);
1510 t_oc->set_location(*t_ref);
1511 if(t_block) {
1512 Obj_defn *t_obj=new Obj_defn(t_block);
1513 t_obj->set_location(*t_block);
1514 ass=new Ass_O(id->clone(), ass_pard, t_oc, t_obj);
1515 }
1516 else {
1517 Obj_refd *t_obj=new Obj_refd(t_ref2);
1518 t_obj->set_location(*t_ref2);
1519 ass=new Ass_O(id->clone(), ass_pard, t_oc, t_obj);
1520 }
1521 ass_pard=0;
1522 left=0;
1523 right=0;
1524 asstype=A_OBJECT;
1525 }
1526 else if(id->isvalid_asn_valref()
1527 && (t_ref=dynamic_cast<Ref_simple*>(left))
1528 && ((t_block=dynamic_cast<Block*>(right))
1529 || (t_ref2=dynamic_cast<Reference*>(right)))
1530 && (t_ref->refers_to_st(Setting::S_T, refch)
1531 || t_ref->refers_to_st(Setting::S_VS, refch))
1532 ) {
1533 Type *t_type=new Type(Type::T_REFD, t_ref);
1534 t_type->set_location(*t_ref);
1535 if(t_block) {
1536 Value *t_value=new Value(Value::V_UNDEF_BLOCK, t_block);
1537 t_value->set_location(*t_block);
1538 ass=new Ass_V(id->clone(), ass_pard, t_type, t_value);
1539 }
1540 else {
1541 Ref_defd_simple *t_ref3=dynamic_cast<Ref_defd_simple*>(t_ref2);
1542 if(t_ref3 && !t_ref3->get_modid()) {
1543 Value *t_val=new Value(Value::V_UNDEF_LOWERID,
1544 t_ref3->get_id()->clone());
1545 t_val->set_location(*t_ref3);
1546 ass=new Ass_V(id->clone(), ass_pard, t_type, t_val);
1547 delete right;
1548 }
1549 else {
1550 Value *t_val=new Value(Value::V_REFD, t_ref2);
1551 t_val->set_location(*t_ref2);
1552 ass=new Ass_V(id->clone(), ass_pard, t_type, t_val);
1553 }
1554 }
1555 ass_pard=0;
1556 left=0;
1557 right=0;
1558 asstype=A_CONST;
1559 }
1560 else {
1561 goto error;
1562 }
1563 goto end;
1564 error:
1565 error("Cannot recognize assignment");
1566 ass = new Ass_Error(id->clone(), ass_pard);
1567 asstype=A_ERROR;
1568 end:
1569 ass->set_location(*this);
1570 ass->set_my_scope(my_scope);
1571 ass->set_right_scope(right_scope);
1572 ass->set_fullname(get_fullname());
1573 if(destroy_refch) delete refch;
1574 else refch->prev_state();
1575 }
1576
1577 // =================================
1578 // ===== Ass_Error
1579 // =================================
1580
1581 Ass_Error::Ass_Error(Identifier *p_id, Ass_pard *p_ass_pard)
1582 : Assignment(A_ERROR, p_id, p_ass_pard),
1583 setting_error(0), type_error(0), value_error(0)
1584 {
1585 }
1586
1587 Ass_Error::~Ass_Error()
1588 {
1589 delete setting_error;
1590 delete type_error;
1591 delete value_error;
1592 }
1593
1594 Assignment* Ass_Error::clone() const
1595 {
1596 return new Ass_Error(id->clone(), ass_pard);
1597 }
1598
1599 Assignment* Ass_Error::new_instance0()
1600 {
1601 return new Ass_Error
1602 (new Identifier(Identifier::ID_ASN, string("<error>")), 0);
1603 }
1604
1605 bool Ass_Error::is_asstype(asstype_t p_asstype, ReferenceChain*)
1606 {
1607 return p_asstype==A_ERROR;
1608 }
1609
1610 Setting* Ass_Error::get_Setting()
1611 {
1612 if(!setting_error)
1613 setting_error = new Common::Setting_Error();
1614 return setting_error;
1615 }
1616
1617 Type* Ass_Error::get_Type()
1618 {
1619 if(!type_error)
1620 type_error = new Type(Type::T_ERROR);
1621 return type_error;
1622 }
1623
1624 Value* Ass_Error::get_Value()
1625 {
1626 if(!value_error)
1627 value_error = new Value(Value::V_ERROR);
1628 return value_error;
1629 }
1630
1631 ValueSet* Ass_Error::get_ValueSet()
1632 {
1633 FATAL_ERROR("Ass_Error::get_ValueSet()");
1634 return 0;
1635 }
1636
1637 ObjectClass* Ass_Error::get_ObjectClass()
1638 {
1639 FATAL_ERROR("Ass_Error::get_ObjectClass()");
1640 return 0;
1641 }
1642
1643 Object* Ass_Error::get_Object()
1644 {
1645 FATAL_ERROR("Ass_Error::get_Object()");
1646 return 0;
1647 }
1648
1649 ObjectSet* Ass_Error::get_ObjectSet()
1650 {
1651 FATAL_ERROR("Ass_Error::get_ObjectSet()");
1652 return 0;
1653 }
1654
1655 void Ass_Error::chk()
1656 {
1657 checked=true;
1658 }
1659
1660 void Ass_Error::dump(unsigned level) const
1661 {
1662 DEBUG(level, "Erroneous assignment: %s%s",
1663 id->get_dispname().c_str(), ass_pard?"{}":"");
1664 }
1665
1666 // =================================
1667 // ===== Ass_T
1668 // =================================
1669
1670 Ass_T::Ass_T(Identifier *p_id, Ass_pard *p_ass_pard, Type *p_right)
1671 : Assignment(A_TYPE, p_id, p_ass_pard)
1672 {
1673 if(!p_right)
1674 FATAL_ERROR("NULL parameter: Asn::Ass_T::Ass_T()");
1675 p_right->set_ownertype(Type::OT_TYPE_ASS, this);
1676 right=p_right;
1677 }
1678
1679 Ass_T::Ass_T(const Ass_T& p)
1680 : Assignment(p)
1681 {
1682 right=p.right->clone();
1683 }
1684
1685 Ass_T::~Ass_T()
1686 {
1687 delete right;
1688 }
1689
1690 Assignment* Ass_T::new_instance0()
1691 {
1692 return new Ass_T
1693 (new Identifier(Identifier::ID_ASN, string("<error>")), 0, right->clone());
1694 }
1695
1696 void Ass_T::set_fullname(const string& p_fullname)
1697 {
1698 Assignment::set_fullname(p_fullname);
1699 right->set_fullname(p_fullname);
1700 }
1701
1702 void Ass_T::set_my_scope(Scope *p_scope)
1703 {
1704 Assignment::set_my_scope(p_scope);
1705 right->set_my_scope(p_scope);
1706 }
1707
1708 void Ass_T::set_right_scope(Scope *p_scope)
1709 {
1710 right->set_my_scope(p_scope);
1711 }
1712
1713 Type* Ass_T::get_Type()
1714 {
1715 if(ass_pard) {
1716 error("`%s' is a parameterized type assignment",
1717 get_fullname().c_str());
1718 return 0;
1719 }
1720 chk();
1721 return right;
1722 }
1723
1724 void Ass_T::chk()
1725 {
1726 if (checked) return;
1727 checked = true;
1728 Error_Context cntxt(this, "In type assignment `%s'",
1729 id->get_dispname().c_str());
1730 if (ass_pard) {
1731 ass_pard->get_nof_pars();
1732 return;
1733 }
1734 chk_ttcn_id();
1735 right->set_genname(get_genname());
1736 right->chk();
1737 ReferenceChain refch(right, "While checking embedded recursions");
1738 right->chk_recursions(refch);
1739 }
1740
1741 void Ass_T::generate_code(output_struct *target, bool)
1742 {
1743 right->generate_code(target);
1744 }
1745
1746 void Ass_T::generate_code(CodeGenHelper& cgh) {
1747 if (ass_pard || dontgen) return;
1748 generate_code(cgh.get_outputstruct(right));
1749 cgh.finalize_generation(right);
1750 }
1751
1752 void Ass_T::dump(unsigned level) const
1753 {
1754 DEBUG(level, "Type assignment: %s%s",
1755 id->get_dispname().c_str(), ass_pard?"{}":"");
1756 level++;
1757 id->dump(level);
1758 if(!ass_pard)
1759 right->dump(level);
1760 }
1761
1762 // =================================
1763 // ===== Ass_V
1764 // =================================
1765
1766 Ass_V::Ass_V(Identifier *p_id, Ass_pard *p_ass_pard,
1767 Type *p_left, Value *p_right)
1768 : Assignment(A_CONST, p_id, p_ass_pard)
1769 {
1770 if(!p_left || !p_right)
1771 FATAL_ERROR("NULL parameter: Asn::Ass_V::Ass_V()");
1772 left=p_left;
1773 left->set_ownertype(Type::OT_VAR_ASS, this);
1774 right=p_right;
1775 }
1776
1777 Ass_V::Ass_V(const Ass_V& p)
1778 : Assignment(p)
1779 {
1780 left=p.left->clone();
1781 right=p.right->clone();
1782 }
1783
1784 Ass_V::~Ass_V()
1785 {
1786 delete left;
1787 delete right;
1788 }
1789
1790 Assignment* Ass_V::new_instance0()
1791 {
1792 return new Ass_V
1793 (new Identifier(Identifier::ID_ASN, string("<error>")), 0,
1794 left->clone(), right->clone());
1795 }
1796
1797 void Ass_V::set_fullname(const string& p_fullname)
1798 {
1799 Assignment::set_fullname(p_fullname);
1800 left->set_fullname(p_fullname + ".<type>");
1801 right->set_fullname(p_fullname);
1802 }
1803
1804 void Ass_V::set_my_scope(Scope *p_scope)
1805 {
1806 Assignment::set_my_scope(p_scope);
1807 left->set_my_scope(p_scope);
1808 right->set_my_scope(p_scope);
1809 }
1810
1811 void Ass_V::set_right_scope(Scope *p_scope)
1812 {
1813 right->set_my_scope(p_scope);
1814 }
1815
1816
1817 Type* Ass_V::get_Type()
1818 {
1819 chk();
1820 return left;
1821 }
1822
1823 Value* Ass_V::get_Value()
1824 {
1825 if(ass_pard) {
1826 error("`%s' is a parameterized value assignment",
1827 get_fullname().c_str());
1828 return 0;
1829 }
1830 chk();
1831 return right;
1832 }
1833
1834 void Ass_V::chk()
1835 {
1836 if(checked) return;
1837 Error_Context cntxt(this, "In value assignment `%s'",
1838 id->get_dispname().c_str());
1839 if(ass_pard) {
1840 ass_pard->get_nof_pars();
1841 checked=true;
1842 return;
1843 }
1844 chk_ttcn_id();
1845 static const string _T_("_T_");
1846 left->set_genname(_T_, get_genname());
1847 left->chk();
1848 right->set_my_governor(left);
1849 left->chk_this_value_ref(right);
1850 checked=true;
1851 left->chk_this_value(right, 0, Type::EXPECTED_CONSTANT, INCOMPLETE_NOT_ALLOWED,
1852 OMIT_NOT_ALLOWED, SUB_CHK, IMPLICIT_OMIT);
1853 {
1854 ReferenceChain refch(right, "While checking embedded recursions");
1855 right->chk_recursions(refch);
1856 }
1857 if (!semantic_check_only) {
1858 right->set_genname_prefix("const_");
1859 right->set_genname_recursive(get_genname());
1860 right->set_code_section(GovernedSimple::CS_PRE_INIT);
1861 }
1862 }
1863
1864 void Ass_V::generate_code(output_struct *target, bool)
1865 {
1866 if (ass_pard || dontgen) return;
1867 left->generate_code(target);
1868 const_def cdef;
1869 Code::init_cdef(&cdef);
1870 left->generate_code_object(&cdef, right);
1871 cdef.init = right->generate_code_init(cdef.init,
1872 right->get_lhs_name().c_str());
1873 Code::merge_cdef(target, &cdef);
1874 Code::free_cdef(&cdef);
1875 }
1876
1877 void Ass_V::generate_code(CodeGenHelper& cgh) {
1878 generate_code(cgh.get_current_outputstruct());
1879 }
1880
1881 void Ass_V::dump(unsigned level) const
1882 {
1883 DEBUG(level, "Value assignment: %s%s",
1884 id->get_dispname().c_str(), ass_pard?"{}":"");
1885 level++;
1886 left->dump(level);
1887 if(!ass_pard)
1888 right->dump(level);
1889 }
1890
1891 // =================================
1892 // ===== Ass_VS
1893 // =================================
1894
1895 Ass_VS::Ass_VS(Identifier *p_id, Ass_pard *p_ass_pard,
1896 Type *p_left, Block *p_right)
1897 : Assignment(A_VS, p_id, p_ass_pard), right_scope(0)
1898 {
1899 if(!p_left || !p_right)
1900 FATAL_ERROR("NULL parameter: Asn::Ass_VS::Ass_VS()");
1901 left=p_left;
1902 left->set_ownertype(Type::OT_VSET_ASS, this);
1903 right=p_right;
1904 }
1905
1906 Ass_VS::Ass_VS(const Ass_VS& p)
1907 : Assignment(p), right_scope(0)
1908 {
1909 left=p.left->clone();
1910 right=p.right->clone();
1911 }
1912
1913 Ass_VS::~Ass_VS()
1914 {
1915 delete left;
1916 delete right;
1917 }
1918
1919 Assignment* Ass_VS::new_instance0()
1920 {
1921 return new Ass_VS
1922 (new Identifier(Identifier::ID_ASN, string("<error>")), 0,
1923 left->clone(), right->clone());
1924 }
1925
1926 void Ass_VS::set_fullname(const string& p_fullname)
1927 {
1928 Assignment::set_fullname(p_fullname);
1929 left->set_fullname(p_fullname);
1930 right->set_fullname(p_fullname);
1931 }
1932
1933 void Ass_VS::set_my_scope(Scope *p_scope)
1934 {
1935 Assignment::set_my_scope(p_scope);
1936 left->set_my_scope(p_scope);
1937 }
1938
1939 void Ass_VS::set_right_scope(Scope *p_scope)
1940 {
1941 right_scope=p_scope;
1942 }
1943
1944 Type* Ass_VS::get_Type()
1945 {
1946 if(ass_pard) {
1947 error("`%s' is a parameterized value set assignment",
1948 get_fullname().c_str());
1949 return 0;
1950 }
1951 chk();
1952 return left;
1953 }
1954
1955 void Ass_VS::chk()
1956 {
1957 if (checked) return;
1958 checked = true;
1959 Error_Context cntxt(this, "In value set assignment `%s'",
1960 id->get_dispname().c_str());
1961 if (ass_pard) {
1962 ass_pard->get_nof_pars();
1963 return;
1964 }
1965
1966 // parse the content of right and add it to left as one more constraint
1967 Node *node = right->parse(KW_Block_ValueSet);
1968 Constraint* vs_constr = dynamic_cast<Constraint*>(node);
1969 if (vs_constr) { // if we have a constraint add it to the type
1970 if (right_scope) { // if this is a parameter of a pard type
1971 vs_constr->set_my_scope(right_scope);
1972 }
1973 if (!left->get_constraints()) left->add_constraints(new Constraints());
1974 left->get_constraints()->add_con(vs_constr);
1975 }
1976
1977 chk_ttcn_id();
1978 left->set_genname(get_genname());
1979 left->chk();
1980 ReferenceChain refch(left, "While checking embedded recursions");
1981 left->chk_recursions(refch);
1982 }
1983
1984 void Ass_VS::generate_code(output_struct *target, bool)
1985 {
1986 left->generate_code(target);
1987 }
1988
1989 void Ass_VS::generate_code(CodeGenHelper& cgh) {
1990 if (ass_pard || dontgen) return;
1991 generate_code(cgh.get_outputstruct(left));
1992 cgh.finalize_generation(left);
1993 }
1994
1995 void Ass_VS::dump(unsigned level) const
1996 {
1997 DEBUG(level, "Value set assignment: %s%s",
1998 id->get_dispname().c_str(), ass_pard?"{}":"");
1999 level++;
2000 id->dump(level);
2001 if(!ass_pard) {
2002 left->dump(level);
2003 right->dump(level);
2004 }
2005 }
2006
2007 // =================================
2008 // ===== Ass_OC
2009 // =================================
2010
2011 Ass_OC::Ass_OC(Identifier *p_id, Ass_pard *p_ass_pard,
2012 ObjectClass *p_right)
2013 : Assignment(A_OC, p_id, p_ass_pard)
2014 {
2015 if(!p_right)
2016 FATAL_ERROR("NULL parameter: Asn::Ass_OC::Ass_OC()");
2017 right=p_right;
2018 }
2019
2020 Ass_OC::Ass_OC(const Ass_OC& p)
2021 : Assignment(p)
2022 {
2023 right=p.right->clone();
2024 }
2025
2026 Ass_OC::~Ass_OC()
2027 {
2028 delete right;
2029 }
2030
2031 Assignment* Ass_OC::new_instance0()
2032 {
2033 return new Ass_OC
2034 (new Identifier(Identifier::ID_ASN, string("<error>")), 0, right->clone());
2035 }
2036
2037 void Ass_OC::set_fullname(const string& p_fullname)
2038 {
2039 Assignment::set_fullname(p_fullname);
2040 right->set_fullname(p_fullname);
2041 }
2042
2043 void Ass_OC::set_my_scope(Scope *p_scope)
2044 {
2045 Assignment::set_my_scope(p_scope);
2046 right->set_my_scope(p_scope);
2047 }
2048
2049 void Ass_OC::set_right_scope(Scope *p_scope)
2050 {
2051 right->set_my_scope(p_scope);
2052 }
2053
2054 void Ass_OC::chk()
2055 {
2056 if(checked) return;
2057 Error_Context cntxt(this, "In information object class assignment `%s'",
2058 id->get_dispname().c_str());
2059 if(ass_pard) {
2060 ass_pard->get_nof_pars();
2061 checked=true;
2062 return;
2063 }
2064 right->set_genname(get_genname());
2065 right->chk();
2066 checked=true;
2067 }
2068
2069 ObjectClass* Ass_OC::get_ObjectClass()
2070 {
2071 if(ass_pard) {
2072 error("`%s' is a parameterized objectclass assignment",
2073 get_fullname().c_str());
2074 return 0;
2075 }
2076 chk();
2077 return right;
2078 }
2079
2080 void Ass_OC::generate_code(output_struct *target, bool)
2081 {
2082 if (ass_pard || dontgen) return;
2083 right->generate_code(target);
2084 }
2085
2086 void Ass_OC::generate_code(CodeGenHelper& cgh) {
2087 generate_code(cgh.get_current_outputstruct());
2088 }
2089
2090 void Ass_OC::dump(unsigned level) const
2091 {
2092 DEBUG(level, "ObjectClass assignment: %s%s",
2093 id->get_dispname().c_str(), ass_pard?"{}":"");
2094 level++;
2095 if(!ass_pard)
2096 right->dump(level);
2097 }
2098
2099 // =================================
2100 // ===== Ass_O
2101 // =================================
2102
2103 Ass_O::Ass_O(Identifier *p_id, Ass_pard *p_ass_pard,
2104 ObjectClass *p_left, Object *p_right)
2105 : Assignment(A_OBJECT, p_id, p_ass_pard)
2106 {
2107 if(!p_left || !p_right)
2108 FATAL_ERROR("NULL parameter: Asn::Ass_O::Ass_O()");
2109 left=p_left;
2110 right=p_right;
2111 }
2112
2113 Ass_O::Ass_O(const Ass_O& p)
2114 : Assignment(p)
2115 {
2116 left=p.left->clone();
2117 right=p.right->clone();
2118 }
2119
2120 Ass_O::~Ass_O()
2121 {
2122 delete left;
2123 delete right;
2124 }
2125
2126 Assignment* Ass_O::new_instance0()
2127 {
2128 return new Ass_O
2129 (new Identifier(Identifier::ID_ASN, string("<error>")), 0,
2130 left->clone(), right->clone());
2131 }
2132
2133 void Ass_O::set_fullname(const string& p_fullname)
2134 {
2135 Assignment::set_fullname(p_fullname);
2136 left->set_fullname(p_fullname);
2137 right->set_fullname(p_fullname);
2138 }
2139
2140 void Ass_O::set_my_scope(Scope *p_scope)
2141 {
2142 Assignment::set_my_scope(p_scope);
2143 left->set_my_scope(p_scope);
2144 right->set_my_scope(p_scope);
2145 }
2146
2147 void Ass_O::set_right_scope(Scope *p_scope)
2148 {
2149 right->set_my_scope(p_scope);
2150 }
2151
2152 /*
2153 ObjectClass* Ass_O::get_ObjectClass()
2154 {
2155 return left;
2156 }
2157 */
2158
2159 Object* Ass_O::get_Object()
2160 {
2161 if(ass_pard) {
2162 error("`%s' is a parameterized object assignment",
2163 get_fullname().c_str());
2164 return 0;
2165 }
2166 chk();
2167 return right;
2168 }
2169
2170 void Ass_O::chk()
2171 {
2172 if(checked) return;
2173 Error_Context cntxt(this, "In information object assignment `%s'",
2174 id->get_dispname().c_str());
2175 if(ass_pard) {
2176 ass_pard->get_nof_pars();
2177 checked=true;
2178 return;
2179 }
2180 left->chk();
2181 right->set_my_governor(left);
2182 right->set_genname(get_genname());
2183 right->chk();
2184 checked=true;
2185 }
2186
2187 void Ass_O::generate_code(output_struct *target, bool)
2188 {
2189 if (ass_pard || dontgen) return;
2190 left->generate_code(target);
2191 right->generate_code(target);
2192 }
2193
2194 void Ass_O::generate_code(CodeGenHelper& cgh) {
2195 generate_code(cgh.get_current_outputstruct());
2196 }
2197
2198 void Ass_O::dump(unsigned level) const
2199 {
2200 DEBUG(level, "Object assignment: %s%s",
2201 id->get_dispname().c_str(), ass_pard?"{}":"");
2202 level++;
2203 left->dump(level);
2204 if(!ass_pard)
2205 right->dump(level);
2206 }
2207
2208 // =================================
2209 // ===== Ass_OS
2210 // =================================
2211
2212 Ass_OS::Ass_OS(Identifier *p_id, Ass_pard *p_ass_pard,
2213 ObjectClass *p_left, ObjectSet *p_right)
2214 : Assignment(A_OS, p_id, p_ass_pard)
2215 {
2216 if(!p_left || !p_right)
2217 FATAL_ERROR("NULL parameter: Asn::Ass_OS::Ass_OS()");
2218 left=p_left;
2219 right=p_right;
2220 }
2221
2222 Ass_OS::Ass_OS(const Ass_OS& p)
2223 : Assignment(p)
2224 {
2225 left=p.left->clone();
2226 right=p.right->clone();
2227 }
2228
2229 Ass_OS::~Ass_OS()
2230 {
2231 delete left;
2232 delete right;
2233 }
2234
2235 Assignment* Ass_OS::new_instance0()
2236 {
2237 return new Ass_OS
2238 (new Identifier(Identifier::ID_ASN, string("<error>")), 0,
2239 left->clone(), right->clone());
2240 }
2241
2242 void Ass_OS::set_fullname(const string& p_fullname)
2243 {
2244 Assignment::set_fullname(p_fullname);
2245 left->set_fullname(p_fullname);
2246 right->set_fullname(p_fullname);
2247 }
2248
2249 void Ass_OS::set_my_scope(Scope *p_scope)
2250 {
2251 Assignment::set_my_scope(p_scope);
2252 left->set_my_scope(p_scope);
2253 right->set_my_scope(p_scope);
2254 }
2255
2256 void Ass_OS::set_right_scope(Scope *p_scope)
2257 {
2258 right->set_my_scope(p_scope);
2259 }
2260
2261 /*
2262 ObjectClass* Ass_OS::get_ObjectClass()
2263 {
2264 return left;
2265 }
2266 */
2267
2268 ObjectSet* Ass_OS::get_ObjectSet()
2269 {
2270 if(ass_pard) {
2271 error("`%s' is a parameterized objectset assignment",
2272 get_fullname().c_str());
2273 return 0;
2274 }
2275 chk();
2276 return right;
2277 }
2278
2279 void Ass_OS::chk()
2280 {
2281 if(checked) return;
2282 Error_Context cntxt(this, "In information object set assignment `%s'",
2283 id->get_dispname().c_str());
2284 if(ass_pard) {
2285 ass_pard->get_nof_pars();
2286 checked=true;
2287 return;
2288 }
2289 left->chk();
2290 right->set_my_governor(left);
2291 right->set_genname(get_genname());
2292 right->chk();
2293 checked=true;
2294 }
2295
2296 void Ass_OS::generate_code(output_struct *target, bool)
2297 {
2298 if (ass_pard || dontgen) return;
2299 left->generate_code(target);
2300 right->generate_code(target);
2301 }
2302
2303 void Ass_OS::generate_code(CodeGenHelper& cgh) {
2304 generate_code(cgh.get_current_outputstruct());
2305 }
2306
2307 void Ass_OS::dump(unsigned level) const
2308 {
2309 DEBUG(level, "ObjectSet assignment: %s%s",
2310 id->get_dispname().c_str(), ass_pard?"{}":"");
2311 level++;
2312 left->dump(level);
2313 if(!ass_pard)
2314 right->dump(level);
2315 }
2316
2317 // =================================
2318 // ===== Reference
2319 // =================================
2320
2321 // =================================
2322 // ===== Ref_defd
2323 // =================================
2324
2325 const Identifier* Ref_defd::get_modid()
2326 {
2327 Ref_defd_simple *t_ref = get_ref_defd_simple();
2328 if (t_ref) return t_ref->get_modid();
2329 else return 0;
2330 }
2331
2332 const Identifier* Ref_defd::get_id()
2333 {
2334 Ref_defd_simple *t_ref = get_ref_defd_simple();
2335 if (t_ref) return t_ref->get_id();
2336 else return 0;
2337 }
2338
2339 bool Ref_defd::refers_to_st(Setting::settingtype_t p_st,
2340 ReferenceChain* refch)
2341 {
2342 if(get_is_erroneous()) return p_st==Setting::S_ERROR;
2343 bool b=false;
2344 Error_Context cntxt(this, "In reference `%s'", get_dispname().c_str());
2345 if(!my_scope)
2346 FATAL_ERROR("NULL parameter");
2347 Common::Assignment* c_ass=my_scope->get_ass_bySRef(this);
2348 if(!c_ass) {
2349 is_erroneous=true;
2350 return false;
2351 }
2352 Assignment* ass=dynamic_cast<Assignment*>(c_ass);
2353 if(!ass) {
2354 error("Reference to a non-ASN setting");
2355 is_erroneous=true;
2356 return false;
2357 }
2358 switch(p_st) {
2359 case Setting::S_OC:
2360 b=ass->is_asstype(Assignment::A_OC, refch);
2361 break;
2362 case Setting::S_T:
2363 b=ass->is_asstype(Assignment::A_TYPE, refch);
2364 break;
2365 case Setting::S_O:
2366 b=ass->is_asstype(Assignment::A_OBJECT, refch);
2367 break;
2368 case Setting::S_V:
2369 b=ass->is_asstype(Assignment::A_CONST, refch);
2370 break;
2371 case Setting::S_OS:
2372 b=ass->is_asstype(Assignment::A_OS, refch);
2373 break;
2374 case Setting::S_VS:
2375 b=ass->is_asstype(Assignment::A_VS, refch);
2376 break;
2377 case Setting::S_ERROR:
2378 b=ass->is_asstype(Assignment::A_ERROR, refch);
2379 break;
2380 default:
2381 FATAL_ERROR("Asn::Ref_defd::refers_to_st()");
2382 } // switch
2383 return b;
2384 }
2385
2386 void Ref_defd::generate_code(expression_struct_t *)
2387 {
2388 FATAL_ERROR("Ref_defd::generate_code()");
2389 }
2390
2391 void Ref_defd::generate_code_const_ref(expression_struct */*expr*/)
2392 {
2393 FATAL_ERROR("Ref_defd::generate_code_const_ref()");
2394 }
2395
2396 // =================================
2397 // ===== Ref_defd_simple
2398 // =================================
2399
2400 Ref_defd_simple::Ref_defd_simple(Identifier *p_modid,
2401 Identifier *p_id)
2402 : Ref_defd(), modid(p_modid), id(p_id)
2403 {
2404 if(!p_id)
2405 FATAL_ERROR("NULL parameter: Asn::Ref_defd_simple::Ref_defd_simple()");
2406 }
2407
2408 Ref_defd_simple::Ref_defd_simple(const Ref_defd_simple& p)
2409 : Ref_defd(p)
2410 {
2411 modid=p.modid?p.modid->clone():0;
2412 id=p.id->clone();
2413 }
2414
2415 Ref_defd_simple::~Ref_defd_simple()
2416 {
2417 delete modid;
2418 delete id;
2419 }
2420
2421 Assignment* Ref_defd_simple::get_refd_ass()
2422 {
2423 if(get_is_erroneous()) return 0;
2424 Error_Context cntxt(this, "In reference `%s'", get_dispname().c_str());
2425 if(!my_scope)
2426 FATAL_ERROR("NULL parameter: Asn::Ref_defd_simple::get_refd_ass():"
2427 " my_scope is not set");
2428 Common::Assignment* c_ass=my_scope->get_ass_bySRef(this);
2429 if(!c_ass) return 0;
2430 Assignment* ass=dynamic_cast<Assignment*>(c_ass);
2431 if(!ass)
2432 this->error("Reference to a non-ASN assignment");
2433 return ass;
2434 }
2435
2436} // namespace Asn
This page took 0.115405 seconds and 5 git commands to generate.