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