Use LTTngUSTLogger logger plugin in logtest regression test
[deliverable/titan.core.git] / compiler2 / Typestuff.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 * Balasko, Jeno
10 * Delic, Adam
11 * Feher, Csaba
12 * Forstner, Matyas
13 * Gecse, Roland
14 * Kovacs, Ferenc
15 * Raduly, Csaba
16 * Szabados, Kristof
17 * Szabo, Janos Zoltan – initial implementation
18 * Szalai, Gabor
19 * Tatarka, Gabor
20 * Zalanyi, Balazs Andor
21 *
22 ******************************************************************************/
23 #include "Typestuff.hh"
24 #include "CompField.hh"
25 #include "asn1/Tag.hh"
26 #include "main.hh"
27
28 namespace Common {
29
30 using Asn::TagDefault;
31
32 // =================================
33 // ===== ExcSpec
34 // =================================
35
36 ExcSpec::ExcSpec(Type *p_type, Value *p_value)
37 : Node()
38 {
39 if(!p_value)
40 FATAL_ERROR("NULL parameter: Asn::ExcSpec::ExcSpec()");
41 type=p_type?p_type:new Type(Type::T_INT);
42 type->set_ownertype(Type::OT_EXC_SPEC, this);
43 value=p_value;
44 }
45
46 ExcSpec::ExcSpec(const ExcSpec& p)
47 : Node(p)
48 {
49 type=p.type->clone();
50 value=p.value->clone();
51 }
52
53 ExcSpec::~ExcSpec()
54 {
55 delete type;
56 delete value;
57 }
58
59 ExcSpec *ExcSpec::clone() const
60 {
61 return new ExcSpec(*this);
62 }
63
64 void ExcSpec::set_my_scope(Scope *p_scope)
65 {
66 type->set_my_scope(p_scope);
67 value->set_my_scope(p_scope);
68 }
69
70 void ExcSpec::set_fullname(const string& p_fullname)
71 {
72 Node::set_fullname(p_fullname);
73 type->set_fullname(p_fullname);
74 value->set_fullname(p_fullname);
75 }
76
77 // =================================
78 // ===== CTs
79 // =================================
80
81 CTs::~CTs()
82 {
83 for(size_t i=0; i<cts.size(); i++) delete cts[i];
84 cts.clear();
85 }
86
87 CTs::CTs(const CTs& p)
88 : Node(p)
89 {
90 for(size_t i=0; i<p.cts.size(); i++)
91 cts.add(p.cts[i]->clone());
92 }
93
94 CTs *CTs::clone() const
95 {
96 return new CTs(*this);
97 }
98
99 void CTs::set_fullname(const string& p_fullname)
100 {
101 Node::set_fullname(p_fullname);
102 for(size_t i=0; i<cts.size(); i++)
103 // cts[i]->set_fullname(get_fullname()+"."+Int2string(i+1));
104 cts[i]->set_fullname(get_fullname());
105 }
106
107 void CTs::set_my_scope(Scope *p_scope)
108 {
109 for(size_t i=0; i<cts.size(); i++)
110 cts[i]->set_my_scope(p_scope);
111 }
112
113 size_t CTs::get_nof_comps() const
114 {
115 size_t n=0;
116 for(size_t i=0; i<cts.size(); i++)
117 n+=cts[i]->get_nof_comps();
118 return n;
119 }
120
121 CompField* CTs::get_comp_byIndex(size_t n) const
122 {
123 size_t offset = n;
124 for(size_t i = 0; i < cts.size(); i++) {
125 size_t size = cts[i]->get_nof_comps();
126 if (offset < size) return cts[i]->get_comp_byIndex(offset);
127 else offset -= size;
128 }
129 FATAL_ERROR("%s: Requested index %lu does not exist.", \
130 get_fullname().c_str(), (unsigned long) n);
131 return 0;
132 }
133
134 bool CTs::has_comp_withName(const Identifier& p_name) const
135 {
136 for(size_t i=0; i<cts.size(); i++)
137 if(cts[i]->has_comp_withName(p_name)) return true;
138 return false;
139 }
140
141 CompField* CTs::get_comp_byName(const Identifier& p_name) const
142 {
143 for(size_t i=0; i<cts.size(); i++)
144 if(cts[i]->has_comp_withName(p_name))
145 return cts[i]->get_comp_byName(p_name);
146 FATAL_ERROR("`%s': No component with name `%s'", \
147 get_fullname().c_str(), p_name.get_dispname().c_str());
148 return 0;
149 }
150
151 void CTs::tr_compsof(ReferenceChain *refch, bool is_set)
152 {
153 for(size_t i = 0; i < cts.size(); i++)
154 cts[i]->tr_compsof(refch, is_set);
155 }
156
157 void CTs::add_ct(CT* p_ct)
158 {
159 if(!p_ct)
160 FATAL_ERROR("NULL parameter: Asn::CTs::add_ct()");
161 cts.add(p_ct);
162 }
163
164 void CTs::dump(unsigned level) const
165 {
166 for(size_t i=0; i<cts.size(); i++)
167 cts[i]->dump(level);
168 }
169
170 // =================================
171 // ===== CTs_EE_CTs
172 // =================================
173
174 CTs_EE_CTs::CTs_EE_CTs(CTs *p_cts1, ExtAndExc *p_ee, CTs *p_cts2)
175 : Node(), my_type(0), checked(false)
176 {
177 cts1 = p_cts1? p_cts1 : new CTs;
178 ee = p_ee;
179 cts2 = p_cts2 ? p_cts2 : new CTs;
180 }
181
182 CTs_EE_CTs::~CTs_EE_CTs()
183 {
184 delete cts1;
185 delete ee;
186 delete cts2;
187 comps_v.clear();
188 comps_m.clear();
189 }
190
191 CTs_EE_CTs::CTs_EE_CTs(const CTs_EE_CTs& p)
192 : Node(p), my_type(p.my_type), checked(false)
193 {
194 cts1 = p.cts1->clone();
195 ee = p.ee ? p.ee->clone() : 0;
196 cts2 = p.cts2->clone();
197 }
198
199 CTs_EE_CTs *CTs_EE_CTs::clone() const
200 {
201 return new CTs_EE_CTs(*this);
202 }
203
204 void CTs_EE_CTs::set_fullname(const string& p_fullname)
205 {
206 Node::set_fullname(p_fullname);
207 cts1->set_fullname(p_fullname);
208 if (ee) ee->set_fullname(p_fullname);
209 cts2->set_fullname(p_fullname);
210 }
211
212 void CTs_EE_CTs::set_my_scope(Scope *p_scope)
213 {
214 cts1->set_my_scope(p_scope);
215 if (ee) ee->set_my_scope(p_scope);
216 cts2->set_my_scope(p_scope);
217 }
218
219 size_t CTs_EE_CTs::get_nof_comps()
220 {
221 if (!checked) chk();
222 return comps_v.size();
223 }
224
225 size_t CTs_EE_CTs::get_nof_root_comps()
226 {
227 return cts1->get_nof_comps() + cts2->get_nof_comps();
228 }
229
230 CompField* CTs_EE_CTs::get_comp_byIndex(size_t n)
231 {
232 if (!checked) chk();
233 return comps_v[n];
234 }
235
236 CompField* CTs_EE_CTs::get_root_comp_byIndex(size_t n)
237 {
238 size_t cts1_size = cts1->get_nof_comps();
239 if (n < cts1_size) return cts1->get_comp_byIndex(n);
240 else return cts2->get_comp_byIndex(n - cts1_size);
241 }
242
243 bool CTs_EE_CTs::has_comp_withName(const Identifier& p_name)
244 {
245 if (!checked) chk();
246 return comps_m.has_key(p_name.get_name());
247 }
248
249 CompField* CTs_EE_CTs::get_comp_byName(const Identifier& p_name)
250 {
251 if (!checked) chk();
252 return comps_m[p_name.get_name()];
253 }
254
255 void CTs_EE_CTs::tr_compsof(ReferenceChain *refch, bool in_ellipsis)
256 {
257 if (!my_type) FATAL_ERROR("NULL parameter: CTs_EE_CTs::tr_compsof()");
258 bool is_set = my_type->get_typetype() == Type::T_SET_A;
259 if (in_ellipsis) {
260 if (ee) ee->tr_compsof(refch, is_set);
261 } else {
262 cts1->tr_compsof(refch, is_set);
263 cts2->tr_compsof(refch, is_set);
264 }
265 }
266
267 bool CTs_EE_CTs::needs_auto_tags()
268 {
269 if (!my_type) FATAL_ERROR("NULL parameter: CTs_EE_CTs::needs_auto_tags()");
270 Asn::Module *m = dynamic_cast<Asn::Module*>
271 (my_type->get_my_scope()->get_scope_mod());
272 if (!m) FATAL_ERROR("CTs_EE_CTs::needs_auto_tags()");
273 if (m->get_tagdef() != TagDefault::AUTOMATIC) return false;
274 for (size_t i = 0; i < cts1->get_nof_comps(); i++) {
275 if (cts1->get_comp_byIndex(i)->get_type()->is_tagged())
276 return false;
277 }
278 for (size_t i = 0; i < cts2->get_nof_comps(); i++) {
279 if (cts2->get_comp_byIndex(i)->get_type()->is_tagged())
280 return false;
281 }
282 if (ee) {
283 bool error_flag = false;
284 for (size_t i = 0; i < ee->get_nof_comps(); i++) {
285 CompField *cf = ee->get_comp_byIndex(i);
286 Type *type = cf->get_type();
287 if (type->is_tagged()) {
288 type->error("Extension addition `%s' cannot have tags because "
289 "the extension root has no tags",
290 cf->get_name().get_dispname().c_str());
291 error_flag = true;
292 }
293 }
294 if (error_flag) return false;
295 }
296 return true;
297 }
298
299 void CTs_EE_CTs::add_auto_tags()
300 {
301 Int tagvalue = 0;
302 for (size_t i = 0; i < cts1->get_nof_comps(); i++) {
303 Tag *tag = new Tag(Tag::TAG_DEFPLICIT, Tag::TAG_CONTEXT, tagvalue++);
304 tag->set_automatic();
305 cts1->get_comp_byIndex(i)->get_type()->add_tag(tag);
306 }
307 for (size_t i = 0; i < cts2->get_nof_comps(); i++) {
308 Tag *tag = new Tag(Tag::TAG_DEFPLICIT, Tag::TAG_CONTEXT, tagvalue++);
309 tag->set_automatic();
310 cts2->get_comp_byIndex(i)->get_type()->add_tag(tag);
311 }
312 if (ee) {
313 for (size_t i = 0; i < ee->get_nof_comps(); i++) {
314 Tag *tag = new Tag(Tag::TAG_DEFPLICIT, Tag::TAG_CONTEXT, tagvalue++);
315 tag->set_automatic();
316 ee->get_comp_byIndex(i)->get_type()->add_tag(tag);
317 }
318 }
319 }
320
321 void CTs_EE_CTs::chk()
322 {
323 // Hack: for COMPONENTS OF transformation
324 // Type::chk() should not be called until the transformation is finished,
325 // but Type::get_type_refd() calls it from CT_CompsOf::tr_compsof().
326 // if (checked) return;
327 if (!my_type) FATAL_ERROR("CTs_EE_CTs::chk()");
328 checked = true;
329 comps_v.clear();
330 comps_m.clear();
331 const char *type_name;
332 const char *comp_name;
333 switch (my_type->get_typetype()) {
334 case Type::T_SEQ_A:
335 type_name = "SEQUENCE";
336 comp_name = "component";
337 break;
338 case Type::T_SET_A:
339 type_name = "SET";
340 comp_name = "component";
341 break;
342 case Type::T_CHOICE_A:
343 type_name = "CHOICE";
344 comp_name = "alternative";
345 break;
346 default:
347 type_name = "<unknown>";
348 comp_name = "component";
349 break;
350 }
351 size_t cts1_size = cts1->get_nof_comps();
352 for (size_t i = 0; i < cts1_size; i++) {
353 chk_comp_field(cts1->get_comp_byIndex(i), type_name, comp_name);
354 }
355 if (ee) {
356 size_t ee_size = ee->get_nof_comps();
357 for (size_t i = 0; i < ee_size; i++) {
358 chk_comp_field(ee->get_comp_byIndex(i), type_name, comp_name);
359 }
360 }
361 size_t cts2_size = cts2->get_nof_comps();
362 for (size_t i = 0; i < cts2_size; i++) {
363 chk_comp_field(cts2->get_comp_byIndex(i), type_name, comp_name);
364 }
365 for (size_t i=0; i<comps_v.size(); i++) {
366 CompField *cf=comps_v[i];
367 const Identifier& id = cf->get_name();
368 const char *dispname = id.get_dispname().c_str();
369 Type *type=cf->get_type();
370 type->set_genname(my_type->get_genname_own(), id.get_name());
371 type->set_parent_type(my_type);
372 {
373 Error_Context cntxt(cf, "In type of %s %s `%s'",
374 type_name, comp_name, dispname);
375 type->chk();
376 }
377 if(cf->has_default()) {
378 Value* defval=cf->get_defval();
379 defval->set_my_governor(type);
380 Error_Context cntxt(cf, "In default value of %s %s `%s'", type_name,
381 comp_name, dispname);
382 type->chk_this_value_ref(defval);
383 type->chk_this_value(defval, 0, Type::EXPECTED_CONSTANT,
384 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
385 if (!semantic_check_only) {
386 defval->set_genname_prefix("const_");
387 defval->set_genname_recursive(string(type->get_genname_own()) +
388 "_defval_");
389 defval->set_code_section(GovernedSimple::CS_PRE_INIT);
390 }
391 }
392 }
393 }
394
395 void CTs_EE_CTs::chk_tags()
396 {
397 if (!my_type) FATAL_ERROR("NULL parameter: CTs_EE_CTs::chk_tags()");
398 switch (my_type->get_typetype()) {
399 case Type::T_CHOICE_A:
400 chk_tags_choice();
401 break;
402 case Type::T_SEQ_A:
403 case Type::T_SEQ_T:
404 chk_tags_seq();
405 break;
406 case Type::T_SET_A:
407 case Type::T_SET_T:
408 chk_tags_set();
409 break;
410 default:
411 FATAL_ERROR("CTs_EE_CTs::chk_tags(): invalid typetype");
412 }
413 }
414
415 void CTs_EE_CTs::chk_comp_field(CompField *cf,
416 const char *type_name,
417 const char *comp_name)
418 {
419 const Identifier& id = cf->get_name();
420 const string& name = id.get_name();
421 if(comps_m.has_key(name)) {
422 const char *dispname_str = id.get_dispname().c_str();
423 cf->error("Duplicate %s identifier in %s: `%s'", comp_name, type_name,
424 dispname_str);
425 comps_m[name]->note("%s `%s' is already defined here", comp_name,
426 dispname_str);
427 } else {
428 comps_m.add(name, cf);
429 comps_v.add(cf);
430 if(!id.get_has_valid(Identifier::ID_TTCN))
431 cf->warning("The identifier `%s' is not reachable from TTCN-3",
432 id.get_dispname().c_str());
433
434 }
435 }
436
437 void CTs_EE_CTs::chk_tags_choice()
438 {
439 TagCollection collection;
440 collection.set_location(*my_type);
441 for (size_t i = 0; i < cts1->get_nof_comps(); i++) {
442 CompField *cf = cts1->get_comp_byIndex(i);
443 Type *type = cf->get_type();
444 if (type->has_multiple_tags()) {
445 Error_Context cntxt(type, "In tags of alternative `%s'",
446 cf->get_name().get_dispname().c_str());
447 get_multiple_tags(collection, type);
448 }
449 else {
450 const Tag *tag = type->get_tag();
451 if (collection.hasTag(tag))
452 type->error("Alternative `%s' in CHOICE has non-distinct tag",
453 cf->get_name().get_dispname().c_str());
454 else collection.addTag(tag);
455 }
456 }
457 if (cts2->get_nof_comps() > 0)
458 FATAL_ERROR("CTs_EE_CTs::chk_tags_choice(): cts2 is not empty");
459 if (ee) {
460 collection.setExtensible();
461 Tag greatest_tag(Tag::TAG_EXPLICIT, Tag::TAG_NONE, (Int)0);
462 for (size_t i = 0; i < ee->get_nof_comps(); i++) {
463 CompField *cf = ee->get_comp_byIndex(i);
464 Type *type = cf->get_type();
465 if (type->has_multiple_tags()) {
466 TagCollection coll2;
467 coll2.set_location(*type);
468 get_multiple_tags(coll2, type);
469 if (!coll2.isEmpty()) {
470 if (collection.hasTags(&coll2))
471 type->error
472 ("Alternative `%s' in CHOICE has non-distinct tag(s)",
473 cf->get_name().get_dispname().c_str());
474 else collection.addTags(&coll2);
475 if (greatest_tag < *coll2.getSmallestTag())
476 greatest_tag = *coll2.getGreatestTag();
477 else type->error
478 ("Alternative `%s' must have canonically greater tag(s)"
479 " than all previously added extension alternatives",
480 cf->get_name().get_dispname().c_str());
481 }
482 } else {
483 const Tag *tag = type->get_tag();
484 if (collection.hasTag(tag))
485 type->error("Alternative `%s' in CHOICE has non-distinct tag",
486 cf->get_name().get_dispname().c_str());
487 else collection.addTag(tag);
488 if (greatest_tag < *tag) greatest_tag = *tag;
489 else type->error
490 ("Alternative `%s' must have canonically greater tag"
491 " than all previously added extension alternatives",
492 cf->get_name().get_dispname().c_str());
493 }
494 }
495 }
496 }
497
498 void CTs_EE_CTs::chk_tags_seq()
499 {
500 TagCollection forbidden_tags;
501 forbidden_tags.set_location(*my_type);
502 for (size_t i = 0; i < cts1->get_nof_comps(); i++) {
503 CompField *cf = cts1->get_comp_byIndex(i);
504 bool mandatory = !cf->get_is_optional() && !cf->has_default();
505 chk_tags_seq_comp(forbidden_tags, cf, mandatory);
506 }
507 size_t j = 0;
508 if (ee) {
509 forbidden_tags.setExtensible();
510 TagCollection forbidden_tags2;
511 forbidden_tags2.set_location(*my_type);
512 forbidden_tags2.setExtensible();
513 for ( ; j < cts2->get_nof_comps(); j++) {
514 CompField *cf = cts2->get_comp_byIndex(j);
515 bool mandatory = !cf->get_is_optional() && !cf->has_default();
516 chk_tags_seq_comp(forbidden_tags, cf, false);
517 chk_tags_seq_comp(forbidden_tags2, cf, false);
518 if (mandatory) {
519 j++;
520 break;
521 }
522 }
523 for (size_t i = 0; i < ee->get_nof_comps(); i++) {
524 CompField *cf = ee->get_comp_byIndex(i);
525 bool mandatory = !cf->get_is_optional() && !cf->has_default();
526 chk_tags_seq_comp(forbidden_tags, cf, mandatory);
527 if (mandatory) {
528 forbidden_tags.clear();
529 forbidden_tags.addTags(&forbidden_tags2);
530 }
531 }
532 }
533 forbidden_tags.clear();
534 for ( ; j < cts2->get_nof_comps(); j++) {
535 CompField *cf = cts2->get_comp_byIndex(j);
536 bool mandatory = !cf->get_is_optional() && !cf->has_default();
537 chk_tags_seq_comp(forbidden_tags, cf, mandatory);
538 }
539 }
540
541 void CTs_EE_CTs::chk_tags_seq_comp(TagCollection& coll, CompField *cf,
542 bool is_mandatory)
543 {
544 Type *type = cf->get_type();
545 bool is_empty = coll.isEmpty();
546 if (!is_mandatory || !is_empty) {
547 if (type->has_multiple_tags()) {
548 Error_Context cntxt(type, "While checking tags of component `%s'",
549 cf->get_name().get_dispname().c_str());
550 get_multiple_tags(coll, type);
551 }
552 else {
553 const Tag *tag = type->get_tag();
554 if(coll.hasTag(tag))
555 type->error("Tag of component `%s' is not allowed "
556 "in this context of SEQUENCE type",
557 cf->get_name().get_dispname().c_str());
558 else coll.addTag(tag);
559 }
560 }
561 if (is_mandatory && !is_empty) coll.clear();
562 }
563
564 void CTs_EE_CTs::chk_tags_set()
565 {
566 TagCollection collection;
567 collection.set_location(*my_type);
568 for (size_t i = 0; i < cts1->get_nof_comps(); i++) {
569 CompField *cf = cts1->get_comp_byIndex(i);
570 Type *type = cf->get_type();
571 if (type->has_multiple_tags()) {
572 Error_Context cntxt(type, "While checking tags of component `%s'",
573 cf->get_name().get_dispname().c_str());
574 get_multiple_tags(collection, type);
575 }
576 else {
577 const Tag *tag = type->get_tag();
578 if (collection.hasTag(tag))
579 type->error("Component `%s' in SET has non-distinct tag",
580 cf->get_name().get_dispname().c_str());
581 else collection.addTag(tag);
582 }
583 }
584 for (size_t i = 0; i < cts2->get_nof_comps(); i++) {
585 CompField *cf = cts2->get_comp_byIndex(i);
586 Type *type = cf->get_type();
587 if (type->has_multiple_tags()) {
588 Error_Context cntxt(type, "While checking tags of component `%s'",
589 cf->get_name().get_dispname().c_str());
590 get_multiple_tags(collection, type);
591 }
592 else {
593 const Tag *tag = type->get_tag();
594 if (collection.hasTag(tag))
595 type->error("Component `%s' in SET has non-distinct tag",
596 cf->get_name().get_dispname().c_str());
597 else collection.addTag(tag);
598 }
599 }
600 if (ee) {
601 collection.setExtensible();
602 Tag greatest_tag(Tag::TAG_EXPLICIT, Tag::TAG_NONE, (Int)0);
603 for (size_t i = 0; i < ee->get_nof_comps(); i++) {
604 CompField *cf = ee->get_comp_byIndex(i);
605 Type *type = cf->get_type();
606 if (type->has_multiple_tags()) {
607 TagCollection coll2;
608 coll2.set_location(*type);
609 get_multiple_tags(coll2, type);
610 if (!coll2.isEmpty()) {
611 if (collection.hasTags(&coll2))
612 type->error("Component `%s' in SET has non-distinct tag(s)",
613 cf->get_name().get_dispname().c_str());
614 else collection.addTags(&coll2);
615 if (greatest_tag < *coll2.getSmallestTag())
616 greatest_tag = *coll2.getGreatestTag();
617 else type->error
618 ("Component `%s' must have "
619 "canonically greater tag(s) than all previously added "
620 "extension components",
621 cf->get_name().get_dispname().c_str());
622 }
623 } else {
624 const Tag *tag = type->get_tag();
625 if (collection.hasTag(tag))
626 type->error("Component `%s' in SET has non-distinct tag",
627 cf->get_name().get_dispname().c_str());
628 else collection.addTag(tag);
629 if (greatest_tag < *tag) greatest_tag = *tag;
630 else type->error
631 ("Component `%s' must have canonically greater "
632 "tag than all previously added extension components",
633 cf->get_name().get_dispname().c_str());
634 }
635 }
636 }
637 }
638
639 /** \todo revise */
640 void CTs_EE_CTs::get_multiple_tags(TagCollection& coll, Type *type)
641 {
642 Type *t=type->get_type_refd_last();
643 if(t->get_typetype()!=Type::T_CHOICE_A)
644 FATAL_ERROR("CTs_EE_CTs::get_multiple_tags()");
645 map<Type*, void> chain;
646 if(my_type->get_typetype()==Type::T_CHOICE_A)
647 chain.add(my_type, 0);
648 t->get_tags(coll, chain);
649 chain.clear();
650 }
651
652 void CTs_EE_CTs::dump(unsigned level) const
653 {
654 if(cts1) cts1->dump(level);
655 if(ee) ee->dump(level);
656 if(cts2) cts2->dump(level);
657 }
658
659 // =================================
660 // ===== ExtAdd
661 // =================================
662
663 // =================================
664 // ===== ExtAdds
665 // =================================
666
667 ExtAdds::~ExtAdds()
668 {
669 for(size_t i=0; i<eas.size(); i++) delete eas[i];
670 eas.clear();
671 }
672
673 ExtAdds *ExtAdds::clone() const
674 {
675 FATAL_ERROR("ExtAdds::clone");
676 }
677
678 void ExtAdds::set_fullname(const string& p_fullname)
679 {
680 Node::set_fullname(p_fullname);
681 for(size_t i=0; i<eas.size(); i++)
682 // eas[i]->set_fullname(get_fullname()+"."+Int2string(i+1));
683 eas[i]->set_fullname(get_fullname());
684 }
685
686 void ExtAdds::set_my_scope(Scope *p_scope)
687 {
688 for(size_t i=0; i<eas.size(); i++)
689 eas[i]->set_my_scope(p_scope);
690 }
691
692 size_t ExtAdds::get_nof_comps() const
693 {
694 size_t n=0;
695 for(size_t i=0; i<eas.size(); i++)
696 n+=eas[i]->get_nof_comps();
697 return n;
698 }
699
700 CompField* ExtAdds::get_comp_byIndex(size_t n) const
701 {
702 size_t offset = n;
703 for(size_t i = 0; i < eas.size(); i++) {
704 size_t size = eas[i]->get_nof_comps();
705 if (offset < size) return eas[i]->get_comp_byIndex(offset);
706 else offset -= size;
707 }
708 FATAL_ERROR("%s: Requested index %lu does not exist.", \
709 get_fullname().c_str(), (unsigned long) n);
710 return 0;
711 }
712
713 bool ExtAdds::has_comp_withName(const Identifier& p_name) const
714 {
715 for(size_t i=0; i<eas.size(); i++)
716 if(eas[i]->has_comp_withName(p_name)) return true;
717 return false;
718 }
719
720 CompField* ExtAdds::get_comp_byName(const Identifier& p_name) const
721 {
722 for(size_t i=0; i<eas.size(); i++)
723 if(eas[i]->has_comp_withName(p_name))
724 return eas[i]->get_comp_byName(p_name);
725 FATAL_ERROR("%s: No component with name `%s'", \
726 get_fullname().c_str(), p_name.get_dispname().c_str());
727 return 0;
728 }
729
730 void ExtAdds::tr_compsof(ReferenceChain *refch, bool is_set)
731 {
732 for(size_t i = 0; i < eas.size(); i++)
733 eas[i]->tr_compsof(refch, is_set);
734 }
735
736 void ExtAdds::add_ea(ExtAdd* p_ea)
737 {
738 if(!p_ea)
739 FATAL_ERROR("NULL parameter: Asn::ExtAdds::add_ea()");
740 eas.add(p_ea);
741 }
742
743 void ExtAdds::dump(unsigned level) const
744 {
745 for(size_t i=0; i<eas.size(); i++)
746 eas[i]->dump(level);
747 }
748
749 // =================================
750 // ===== ExtAndExc
751 // =================================
752
753 ExtAndExc::ExtAndExc(ExcSpec *p_excSpec, ExtAdds *p_eas)
754 : Node()
755 {
756 excSpec=p_excSpec;
757 eas=p_eas?p_eas:new ExtAdds();
758 }
759
760 ExtAndExc::~ExtAndExc()
761 {
762 delete excSpec;
763 delete eas;
764 }
765
766 ExtAndExc *ExtAndExc::clone() const
767 {
768 FATAL_ERROR("ExtAndExc::clone");
769 }
770
771 void ExtAndExc::set_fullname(const string& p_fullname)
772 {
773 Node::set_fullname(p_fullname);
774 if(excSpec) excSpec->set_fullname(p_fullname+".<exc>");
775 // eas->set_fullname(p_fullname+".<ext>");
776 eas->set_fullname(p_fullname);
777 }
778
779 void ExtAndExc::set_my_scope(Scope *p_scope)
780 {
781 if(excSpec) excSpec->set_my_scope(p_scope);
782 eas->set_my_scope(p_scope);
783 }
784
785 void ExtAndExc::set_eas(ExtAdds *p_eas)
786 {
787 delete eas;
788 eas=p_eas;
789 }
790
791 void ExtAndExc::dump(unsigned level) const
792 {
793 DEBUG(level, "...%s", excSpec?" !":"");
794 if(eas) eas->dump(level);
795 DEBUG(level, "...");
796 }
797
798 // =================================
799 // ===== ExtAddGrp
800 // =================================
801
802 ExtAddGrp::ExtAddGrp(Value* p_versionnumber, CTs *p_cts)
803 : ExtAdd()
804 {
805 if(!p_cts)
806 FATAL_ERROR("NULL parameter: Asn::ExtAddGrp::ExtAddGrp()");
807 versionnumber=p_versionnumber;
808 cts=p_cts;
809 }
810
811 ExtAddGrp::~ExtAddGrp()
812 {
813 delete versionnumber;
814 delete cts;
815 }
816
817 ExtAddGrp *ExtAddGrp::clone() const
818 {
819 FATAL_ERROR("ExtAddGrp::clone");
820 }
821
822 void ExtAddGrp::set_fullname(const string& p_fullname)
823 {
824 ExtAdd::set_fullname(p_fullname);
825 if(versionnumber) versionnumber->set_fullname(p_fullname
826 +".<versionnumber>");
827 cts->set_fullname(p_fullname);
828 }
829
830 void ExtAddGrp::set_my_scope(Scope *p_scope)
831 {
832 if(versionnumber) versionnumber->set_my_scope(p_scope);
833 cts->set_my_scope(p_scope);
834 }
835
836 size_t ExtAddGrp::get_nof_comps() const
837 {
838 return cts->get_nof_comps();
839 }
840
841 CompField* ExtAddGrp::get_comp_byIndex(size_t n) const
842 {
843 return cts->get_comp_byIndex(n);
844 }
845
846 bool ExtAddGrp::has_comp_withName(const Identifier& p_name) const
847 {
848 return cts->has_comp_withName(p_name);
849 }
850
851 CompField* ExtAddGrp::get_comp_byName(const Identifier& p_name) const
852 {
853 return cts->get_comp_byName(p_name);
854 }
855
856 void ExtAddGrp::tr_compsof(ReferenceChain *refch, bool is_set)
857 {
858 cts->tr_compsof(refch, is_set);
859 }
860
861 void ExtAddGrp::dump(unsigned level) const
862 {
863 DEBUG(level, "[[");
864 cts->dump(level);
865 DEBUG(level, "]]");
866 }
867
868 // =================================
869 // ===== CT
870 // =================================
871
872 // =================================
873 // ===== CT_reg
874 // =================================
875
876 CT_reg::CT_reg(CompField *p_comp)
877 : CT()
878 {
879 if(!p_comp)
880 FATAL_ERROR("NULL parameter: Asn::CT_reg::CT_reg()");
881 comp=p_comp;
882 }
883
884 CT_reg::~CT_reg()
885 {
886 delete comp;
887 }
888
889 CT_reg *CT_reg::clone() const
890 {
891 FATAL_ERROR("CT_reg::clone");
892 }
893
894 void CT_reg::set_fullname(const string& p_fullname)
895 {
896 comp->set_fullname(p_fullname);
897 }
898
899 void CT_reg::set_my_scope(Scope *p_scope)
900 {
901 comp->set_my_scope(p_scope);
902 }
903
904 size_t CT_reg::get_nof_comps() const
905 {
906 return 1;
907 }
908
909 CompField *CT_reg::get_comp_byIndex(size_t n) const
910 {
911 if (n == 0) return comp;
912 FATAL_ERROR("%s: Requested index %lu does not exist.", \
913 get_fullname().c_str(), (unsigned long) n);
914 return 0;
915 }
916
917 bool CT_reg::has_comp_withName(const Identifier& p_name) const
918 {
919 return comp->get_name() == p_name;
920 }
921
922 CompField *CT_reg::get_comp_byName(const Identifier& p_name) const
923 {
924 if (comp->get_name() == p_name)
925 return comp;
926 FATAL_ERROR("`%s': No component with name `%s'", \
927 get_fullname().c_str(), p_name.get_dispname().c_str());
928 return 0;
929 }
930
931 void CT_reg::tr_compsof(ReferenceChain *, bool)
932 {
933 }
934
935 void CT_reg::dump(unsigned level) const
936 {
937 comp->dump(level);
938 }
939
940
941 // =================================
942 // ===== CT_CompsOf
943 // =================================
944
945 CT_CompsOf::CT_CompsOf(Type *p_compsoftype)
946 : CT(), compsoftype(p_compsoftype), tr_compsof_ready(false), cts(0)
947 {
948 if(!p_compsoftype)
949 FATAL_ERROR("NULL parameter: Asn::CT_CompsOf::CT_CompsOf()");
950 compsoftype->set_ownertype(Type::OT_COMPS_OF, this);
951 }
952
953 CT_CompsOf::~CT_CompsOf()
954 {
955 delete compsoftype;
956 delete cts;
957 }
958
959 CT_CompsOf *CT_CompsOf::clone() const
960 {
961 FATAL_ERROR("CT_CompsOf::clone");
962 }
963
964 void CT_CompsOf::set_fullname(const string& p_fullname)
965 {
966 ExtAdd::set_fullname(p_fullname);
967 if(compsoftype) compsoftype->set_fullname(p_fullname+".<CompsOfType>");
968 if(cts) cts->set_fullname(p_fullname);
969 }
970
971 void CT_CompsOf::set_my_scope(Scope *p_scope)
972 {
973 if (compsoftype) compsoftype->set_my_scope(p_scope);
974 if (cts) cts->set_my_scope(p_scope);
975 }
976
977 size_t CT_CompsOf::get_nof_comps() const
978 {
979 if (cts) return cts->get_nof_comps();
980 else return 0;
981 }
982
983 CompField* CT_CompsOf::get_comp_byIndex(size_t n) const
984 {
985 if (!cts) FATAL_ERROR("CT_CompsOf::get_comp_byIndex()");
986 return cts->get_comp_byIndex(n);
987 }
988
989 bool CT_CompsOf::has_comp_withName(const Identifier& p_name) const
990 {
991 if (cts) return cts->has_comp_withName(p_name);
992 else return false;
993 }
994
995 CompField* CT_CompsOf::get_comp_byName(const Identifier& p_name) const
996 {
997 if (!cts) FATAL_ERROR("CT_CompsOf::get_comp_byName()");
998 return cts->get_comp_byName(p_name);
999 }
1000
1001 void CT_CompsOf::tr_compsof(ReferenceChain *refch, bool is_set)
1002 {
1003 if (tr_compsof_ready) return;
1004 compsoftype->set_genname(string("<dummy>"));
1005 Type *t=compsoftype->get_type_refd_last();
1006 // to avoid re-entering in case of infinite recursion
1007 if (tr_compsof_ready) return;
1008 bool error_flag = true;
1009 if(is_set) {
1010 switch (t->get_typetype()) {
1011 case Type::T_SET_A:
1012 error_flag = false;
1013 break;
1014 case Type::T_ERROR:
1015 break;
1016 case Type::T_SEQ_A:
1017 error_flag = false;
1018 // no break
1019 default:
1020 t->error("COMPONENTS OF in a SET type shall refer to another SET type"
1021 " instead of `%s'", t->get_fullname().c_str());
1022 break;
1023 }
1024 } else {
1025 switch (t->get_typetype()) {
1026 case Type::T_SEQ_A:
1027 error_flag = false;
1028 break;
1029 case Type::T_ERROR:
1030 break;
1031 case Type::T_SET_A:
1032 error_flag = false;
1033 // no break
1034 default:
1035 t->error("COMPONENTS OF in a SEQUENCE type shall refer to another"
1036 " SEQUENCE type instead of `%s'", t->get_fullname().c_str());
1037 break;
1038 }
1039 }
1040 if (error_flag) {
1041 tr_compsof_ready = true;
1042 return;
1043 }
1044 t->tr_compsof(refch);
1045 // another emergency exit for the case of infinite recursion
1046 if (tr_compsof_ready) return;
1047 cts=new CTs;
1048 size_t n_comps=t->get_nof_root_comps();
1049 for(size_t i=0; i<n_comps; i++) {
1050 CompField *cf=t->get_root_comp_byIndex(i)->clone();
1051 cf->get_type()->cut_auto_tags();
1052 cf->set_location(*this);
1053 cts->add_ct(new CT_reg(cf));
1054 }
1055 cts->set_my_scope(compsoftype->get_my_scope());
1056 cts->set_fullname(get_fullname());
1057 tr_compsof_ready=true;
1058 // compsoftype must not be deleted because the above t->get_type_refd()
1059 // call may modify it in case of infinite recursion
1060 }
1061
1062 void CT_CompsOf::dump(unsigned level) const
1063 {
1064 if(compsoftype) {
1065 DEBUG(level, "COMPONENTS OF");
1066 compsoftype->dump(level+1);
1067 }
1068 if(cts) cts->dump(level);
1069 }
1070
1071 } // namespace Common
This page took 0.053862 seconds and 5 git commands to generate.