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