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