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