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