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