Sync with 5.1.0
[deliverable/titan.core.git] / compiler2 / CompType.cc
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "CompType.hh"
9
10 #include "ttcn3/AST_ttcn3.hh"
11 #include "ttcn3/Attributes.hh"
12
13 // implemented in comptype_attrib_la.l
14 extern void parseExtendsCompTypeRefList(Ttcn::AttributeSpec const& attrib,
15 Common::CompTypeRefList*& attr_comp_refs);
16
17 namespace Common {
18
19 // =================================
20 // ===== ComponentTypeBody
21 // =================================
22
23 ComponentTypeBody::~ComponentTypeBody()
24 {
25 for(size_t i = 0; i < def_v.size(); i++) delete def_v[i];
26 def_v.clear();
27 delete extends_refs;
28 delete attr_extends_refs;
29 all_defs_m.clear();
30 orig_defs_m.clear();
31 compatible_m.clear();
32 }
33
34 ComponentTypeBody *ComponentTypeBody::clone() const
35 {
36 FATAL_ERROR("ComponentTypeBody::clone()");
37 }
38
39 void ComponentTypeBody::set_fullname(const string& p_fullname)
40 {
41 Scope::set_fullname(p_fullname);
42 for(size_t i = 0; i < def_v.size(); i++) {
43 Ttcn::Definition *def = def_v[i];
44 def->set_fullname(p_fullname + "." + def->get_id().get_dispname());
45 }
46 if (extends_refs)
47 extends_refs->set_fullname(p_fullname+".<extends>");
48 if (attr_extends_refs)
49 attr_extends_refs->set_fullname(get_fullname()+".<extends attribute>");
50 }
51
52 void ComponentTypeBody::set_my_scope(Scope *p_scope)
53 {
54 set_parent_scope(p_scope);
55 if (extends_refs) extends_refs->set_my_scope(p_scope);
56 if (attr_extends_refs) attr_extends_refs->set_my_scope(p_scope);
57 }
58
59 void ComponentTypeBody::add_extends(CompTypeRefList *p_crl)
60 {
61 if (extends_refs || !p_crl || check_state!=CHECK_INITIAL)
62 FATAL_ERROR("ComponentTypeBody::add_extends()");
63 extends_refs = p_crl;
64 }
65
66 bool ComponentTypeBody::is_compatible(ComponentTypeBody *other)
67 {
68 if (other==this) return true;
69 chk(CHECK_EXTENDS);
70 other->chk(CHECK_EXTENDS);
71 // a component with no definitions is compatible with all components
72 if (def_v.size()==0 && !extends_refs && !attr_extends_refs) return true;
73 return other->compatible_m.has_key(this);
74 }
75
76 void ComponentTypeBody::add_ass(Ttcn::Definition *p_ass)
77 {
78 if (check_state!=CHECK_INITIAL || !p_ass)
79 FATAL_ERROR("ComponentTypeBody::add_ass()");
80 p_ass->set_my_scope(this);
81 def_v.add(p_ass);
82 }
83
84 bool ComponentTypeBody::has_local_ass_withId(const Identifier& p_id)
85 {
86 chk();
87 return all_defs_m.has_key(p_id.get_name());
88 }
89
90 Assignment* ComponentTypeBody::get_local_ass_byId(const Identifier& p_id)
91 {
92 chk();
93 return all_defs_m[p_id.get_name()];
94 }
95
96 size_t ComponentTypeBody::get_nof_asss()
97 {
98 chk();
99 return all_defs_m.size();
100 }
101
102 bool ComponentTypeBody::has_ass_withId(const Identifier& p_id)
103 {
104 if (has_local_ass_withId(p_id)) return true;
105 else if (parent_scope) return parent_scope->has_ass_withId(p_id);
106 else return false;
107 }
108
109 Assignment* ComponentTypeBody::get_ass_byIndex(size_t p_i)
110 {
111 chk();
112 return all_defs_m.get_nth_elem(p_i);
113 }
114
115 bool ComponentTypeBody::is_own_assignment(const Assignment* p_ass)
116 {
117 for(size_t i = 0; i < def_v.size(); i++) {
118 if (def_v[i] == p_ass) return true;
119 }
120 return false;
121 }
122
123 Assignment* ComponentTypeBody::get_ass_bySRef(Ref_simple *p_ref)
124 {
125 if (!p_ref || !parent_scope)
126 FATAL_ERROR("ComponentTypeBody::get_ass_bySRef()");
127 if (!p_ref->get_modid()) {
128 const Identifier *id = p_ref->get_id();
129 if (id && has_local_ass_withId(*id)) {
130 Assignment* ass = get_local_ass_byId(*id);
131 if (!ass) FATAL_ERROR("ComponentTypeBody::get_ass_bySRef()");
132
133 for(size_t i = 0; i < def_v.size(); i++) {
134 if (def_v[i] == ass) return ass;
135 }
136
137 if (ass->get_visibility() == PUBLIC) {
138 return ass;
139 }
140
141 p_ref->error("The member definition `%s' in component type `%s'"
142 " is not visible in this scope", id->get_dispname().c_str(),
143 comp_id->get_dispname().c_str());
144 return 0;
145 }
146 }
147 return parent_scope->get_ass_bySRef(p_ref);
148 }
149
150 void ComponentTypeBody::dump(unsigned level) const
151 {
152 if (extends_refs) {
153 DEBUG(level, "Extends references:");
154 extends_refs->dump(level+1);
155 }
156 DEBUG(level, "Definitions: (%lu pcs.)", (unsigned long) def_v.size());
157 for(size_t i = 0; i < def_v.size(); i++) def_v[i]->dump(level + 1);
158 if (attr_extends_refs) {
159 DEBUG(level, "Extends attribute references:");
160 attr_extends_refs->dump(level+1);
161 }
162 }
163
164 // read out the contents of the with attribute extension,
165 // parse it to the the attr_extends_refs member variable,
166 // collects all extends components from all attributes along the attrib path
167 void ComponentTypeBody::chk_extends_attr()
168 {
169 if (check_state>=CHECK_WITHATTRIB) return;
170 check_state = CHECK_WITHATTRIB;
171 Ttcn::WithAttribPath* w_attrib_path = my_type->get_attrib_path();
172 if(w_attrib_path)
173 {
174 vector<Ttcn::SingleWithAttrib> const &real_attribs =
175 w_attrib_path->get_real_attrib();
176 for (size_t i = 0; i < real_attribs.size(); i++)
177 {
178 Ttcn::SingleWithAttrib *act_attr = real_attribs[i];
179 if (act_attr->get_attribKeyword()==Ttcn::SingleWithAttrib::AT_EXTENSION)
180 parseExtendsCompTypeRefList(act_attr->get_attribSpec(),
181 attr_extends_refs);
182 }
183 }
184 if (attr_extends_refs)
185 {
186 attr_extends_refs->set_fullname(get_fullname()+".<extends attribute>");
187 attr_extends_refs->set_my_scope(parent_scope);
188 }
189 }
190
191 void ComponentTypeBody::chk_recursion(ReferenceChain& refch)
192 {
193 if (refch.add(get_fullname())) {
194 if (extends_refs) extends_refs->chk_recursion(refch);
195 if (attr_extends_refs) attr_extends_refs->chk_recursion(refch);
196 }
197 }
198
199 // contained components must already be checked,
200 // having valid compatible_m maps
201 void ComponentTypeBody::init_compatibility(CompTypeRefList *crl,
202 bool is_standard_extends)
203 {
204 for (size_t i = 0; i < crl->get_nof_comps(); i++)
205 {
206 ComponentTypeBody *cb = crl->get_nth_comp_body(i);
207 if (!compatible_m.has_key(cb))
208 compatible_m.add(cb, is_standard_extends ? cb : NULL);
209 // compatible with all components which are compatible with the compatible
210 // component
211 for (size_t j = 0; j < cb->compatible_m.size(); j++)
212 {
213 ComponentTypeBody *ccb = cb->compatible_m.get_nth_key(j);
214 ComponentTypeBody *ccbval = cb->compatible_m.get_nth_elem(j);
215 if (!compatible_m.has_key(ccb))
216 compatible_m.add(ccb, is_standard_extends ? ccbval : NULL);
217 }
218 }
219 }
220
221 void ComponentTypeBody::chk_extends()
222 {
223 if (check_state>=CHECK_EXTENDS) return;
224 check_state = CHECK_EXTENDS;
225 // check the references in component extends parts (keyword and attribute)
226 if (extends_refs) extends_refs->chk(CHECK_EXTENDS);
227 if (attr_extends_refs) attr_extends_refs->chk(CHECK_EXTENDS);
228 // check for circular reference chains
229 ReferenceChain refch(this, "While checking component type extensions");
230 chk_recursion(refch);
231 // build compatibility map for faster is_compatible() and generate_code()
232 // contained components must already have valid compatible_m map
233 // keys used in is_compatible(), values used in generate_code()
234 if (extends_refs) init_compatibility(extends_refs, true);
235 if (attr_extends_refs) init_compatibility(attr_extends_refs, false);
236 }
237
238 void ComponentTypeBody::collect_defs_from_standard_extends()
239 {
240 Assignments *module_defs = parent_scope->get_scope_asss();
241 for (size_t i = 0; i < extends_refs->get_nof_comps(); i++) {
242 ComponentTypeBody *parent = extends_refs->get_nth_comp_body(i);
243 // iterate through all definitions of the parent
244 // parent is already checked (has it's inherited defs included)
245 for (size_t j = 0; j < parent->all_defs_m.size(); j++) {
246 Ttcn::Definition *def = parent->all_defs_m.get_nth_elem(j);
247 const Identifier& id = def->get_id();
248 const string& name = id.get_name();
249 if (all_defs_m.has_key(name)) {
250 Ttcn::Definition *my_def = all_defs_m[name];
251 if (my_def != def) {
252 // it is not the same definition inherited on two paths
253 const char *dispname_str = id.get_dispname().c_str();
254 if (my_def->get_my_scope() == this) {
255 my_def->error("Local definition `%s' collides with definition "
256 "inherited from component type `%s'", dispname_str,
257 def->get_my_scope()->get_fullname().c_str());
258 def->note("Inherited definition of `%s' is here", dispname_str);
259 } else {
260 error("Definition `%s' inherited from component type `%s' "
261 "collides with definition inherited from `%s'", dispname_str,
262 def->get_my_scope()->get_fullname().c_str(),
263 my_def->get_my_scope()->get_fullname().c_str());
264 def->note("Definition of `%s' in `%s' is here", dispname_str,
265 def->get_my_scope()->get_fullname().c_str());
266 my_def->note("Definition of `%s' in `%s' is here", dispname_str,
267 my_def->get_my_scope()->get_fullname().c_str());
268 }
269 }
270 } else {
271 all_defs_m.add(name, def);
272 if (def->get_my_scope()->get_scope_mod() !=
273 module_defs->get_scope_mod()) {
274 // def comes from another module
275 if (module_defs->has_local_ass_withId(id)) {
276 const char *dispname_str = id.get_dispname().c_str();
277 error("The name of inherited definition `%s' is not unique in "
278 "the scope hierarchy", dispname_str);
279 module_defs->get_local_ass_byId(id)->note("Symbol `%s' is "
280 "already defined here in a higher scope unit", dispname_str);
281 def->note("Definition `%s' inherited from component type `%s' "
282 "is here", dispname_str,
283 def->get_my_scope()->get_fullname().c_str());
284 } else if (module_defs->is_valid_moduleid(id)) {
285 def->warning("Inherited definition with name `%s' hides a "
286 "module identifier", id.get_dispname().c_str());
287 }
288 }
289 }
290 }
291 }
292 }
293
294 void ComponentTypeBody::collect_defs_from_attribute_extends()
295 {
296 for (size_t i = 0; i < attr_extends_refs->get_nof_comps(); i++) {
297 ComponentTypeBody *parent = attr_extends_refs->get_nth_comp_body(i);
298 // iterate through all definitions of the parent
299 // parent is already checked (has it's inherited defs included)
300 for (size_t j = 0; j < parent->all_defs_m.size(); j++) {
301 Ttcn::Definition *def = parent->all_defs_m.get_nth_elem(j);
302 const Identifier& id = def->get_id();
303 const char *dispname_str = id.get_dispname().c_str();
304 const string& name = id.get_name();
305 // the definition to be imported must be already in the all_defs_m map
306 // and must belong to owner (not be inherited)
307 // orig_defs_map contains backed up own definitions
308 if (all_defs_m.has_key(name)) {
309 Ttcn::Definition *my_def = all_defs_m[name];
310 if (my_def->get_my_scope() == this) {
311 // my_def is a local definition
312 if (orig_defs_m.has_key(name)) FATAL_ERROR( \
313 "ComponentTypeBody::collect_defs_from_attribute_extends()");
314 orig_defs_m.add(name, my_def); // backup for init
315 all_defs_m[name] = def; // point to inherited def
316 } else {
317 // my_def comes from another component type
318 // exclude case when the same definition is inherited on different
319 // paths, there must be a local definition
320 if (def!=my_def || !orig_defs_m.has_key(name)) {
321 error("Definition `%s' inherited from component type `%s' "
322 "collides with definition inherited from `%s'", dispname_str,
323 def->get_my_scope()->get_fullname().c_str(),
324 my_def->get_my_scope()->get_fullname().c_str());
325 def->note("Definition of `%s' in `%s' is here",
326 dispname_str, def->get_my_scope()->get_fullname().c_str());
327 my_def->note("Definition of `%s' in `%s' is here",
328 dispname_str, my_def->get_my_scope()->get_fullname().c_str());
329 if (orig_defs_m.has_key(name)) {
330 // the same definition is also present locally
331 orig_defs_m[name]->note("Local definition of `%s' is here",
332 dispname_str);
333 }
334 }
335 }
336 } else {
337 error("Missing local definition of `%s', which was inherited from "
338 "component type `%s'", dispname_str,
339 def->get_my_scope()->get_fullname().c_str());
340 def->note("Inherited definition of `%s' is here", dispname_str);
341 }
342 }
343 }
344 }
345
346 void ComponentTypeBody::chk_defs_uniq()
347 {
348 if (check_state>=CHECK_DEFUNIQ) return;
349 check_state = CHECK_DEFUNIQ;
350 if (extends_refs) extends_refs->chk(CHECK_DEFUNIQ);
351 if (attr_extends_refs) attr_extends_refs->chk(CHECK_DEFUNIQ);
352 size_t nof_defs = def_v.size();
353 if (nof_defs > 0) {
354 Error_Context cntxt(this, "While checking uniqueness of component "
355 "element definitions");
356 Assignments *module_defs = parent_scope->get_scope_asss();
357 // add own definitions to all_def_m
358 for (size_t i = 0; i < nof_defs; i++) {
359 Ttcn::Definition *def = def_v[i];
360 const Identifier& id = def->get_id();
361 const string& name = id.get_name();
362 if (all_defs_m.has_key(name)) {
363 const char *dispname_str = id.get_dispname().c_str();
364 def->error("Duplicate definition with name `%s'", dispname_str);
365 all_defs_m[name]->note("Previous definition of `%s' is here",
366 dispname_str);
367 } else {
368 all_defs_m.add(name, def);
369 if (module_defs->has_local_ass_withId(id)) {
370 const char *dispname_str = id.get_dispname().c_str();
371 def->error("Component element name `%s' is not unique in the "
372 "scope hierarchy", dispname_str);
373 module_defs->get_local_ass_byId(id)->note("Symbol `%s' is "
374 "already defined here in a higher scope unit", dispname_str);
375 } else if (module_defs->is_valid_moduleid(id)) {
376 def->warning("Definition with name `%s' hides a module identifier",
377 id.get_dispname().c_str());
378 }
379 }
380 }
381 }
382 if (extends_refs || attr_extends_refs) {
383 // collect all inherited definitions
384 Error_Context cntxt(this, "While checking uniqueness of inherited "
385 "component element definitions");
386 if (extends_refs) collect_defs_from_standard_extends();
387 if (attr_extends_refs) collect_defs_from_attribute_extends();
388 }
389 }
390
391 void ComponentTypeBody::chk_my_defs()
392 {
393 if (check_state>=CHECK_OWNDEFS) return;
394 check_state = CHECK_OWNDEFS;
395 Error_Context cntxt(this, "In component element definitions");
396 for (size_t i = 0; i < def_v.size(); i++) def_v[i]->chk();
397 }
398
399 void ComponentTypeBody::chk_attr_ext_defs()
400 {
401 if (check_state>=CHECK_EXTDEFS) return;
402 check_state = CHECK_EXTDEFS;
403 size_t nof_inherited_defs = orig_defs_m.size();
404 if (nof_inherited_defs > 0) {
405 Error_Context cntxt(this, "While checking whether the local and "
406 "inherited component element definitions are identical");
407 // for definitions inherited with attribute extends check if
408 // local and inherited definitions are identical
409 for (size_t i = 0; i < nof_inherited_defs; i++) {
410 const string& key = orig_defs_m.get_nth_key(i);
411 Ttcn::Definition *original_def = orig_defs_m.get_nth_elem(i);
412 Ttcn::Definition *inherited_def = all_defs_m[key];
413 if (!original_def->chk_identical(inherited_def))
414 all_defs_m[key] = original_def;
415 }
416 }
417 }
418
419 void ComponentTypeBody::chk(check_state_t required_check_state)
420 {
421 if (checking || check_state==CHECK_FINAL) return;
422 checking = true;
423 switch (check_state)
424 {
425 case CHECK_INITIAL:
426 chk_extends_attr();
427 if (required_check_state==CHECK_WITHATTRIB) break;
428 // no break
429 case CHECK_WITHATTRIB:
430 chk_extends();
431 if (required_check_state==CHECK_EXTENDS) break;
432 // no break
433 case CHECK_EXTENDS:
434 chk_defs_uniq();
435 if (required_check_state==CHECK_DEFUNIQ) break;
436 // no break
437 case CHECK_DEFUNIQ:
438 chk_my_defs();
439 if (required_check_state==CHECK_OWNDEFS) break;
440 // no break
441 case CHECK_OWNDEFS:
442 chk_attr_ext_defs();
443 if (required_check_state==CHECK_EXTDEFS) break;
444 // no break
445 case CHECK_EXTDEFS:
446 check_state = CHECK_FINAL;
447 // no break
448 case CHECK_FINAL:
449 break;
450 default:
451 FATAL_ERROR("ComponentTypeBody::chk()");
452 }
453 checking = false;
454 }
455
456 void ComponentTypeBody::set_genname(const string& prefix)
457 {
458 for (size_t i = 0; i < def_v.size(); i++) {
459 Ttcn::Definition *def = def_v[i];
460 def->set_genname(prefix + def->get_id().get_name());
461 }
462 }
463
464
465 void ComponentTypeBody::generate_code(output_struct* target)
466 {
467 if (check_state != CHECK_FINAL || !comp_id)
468 FATAL_ERROR("ComponentTypeBody::generate_code()");
469 // beginning of block in init_comp
470 target->functions.init_comp = mputprintf(target->functions.init_comp,
471 "if (!strcmp(component_type, \"%s\")) {\n",
472 comp_id->get_dispname().c_str());
473
474 // call init_comp for all components which are compatible
475 // with this component along standard extends paths
476 if (extends_refs) {
477 bool has_base_comps = false;
478 for (size_t i = 0; i < compatible_m.size(); i++) {
479 ComponentTypeBody *cb = compatible_m.get_nth_elem(i);
480 // recursive initialization is needed if the component type is
481 // inherited using the standard "extends" mechanism and the component
482 // type has its own definitions
483 if (cb && cb->def_v.size() > 0) {
484 if (!has_base_comps) {
485 target->functions.init_comp = mputstr(target->functions.init_comp,
486 "if (init_base_comps) {\n");
487 has_base_comps = true;
488 }
489 const char *ct_dispname_str = cb->get_id()->get_dispname().c_str();
490 Module *ct_mod = cb->get_scope_mod_gen();
491 if (ct_mod == get_scope_mod_gen()) {
492 // the other component type is in the same module
493 // call the initializer function recursively
494 target->functions.init_comp = mputprintf(
495 target->functions.init_comp, "init_comp_type(\"%s\", FALSE);\n",
496 ct_dispname_str);
497 } else {
498 // the other component type is imported from another module
499 // use the module list for initialization
500 target->functions.init_comp = mputprintf(
501 target->functions.init_comp,
502 "Module_List::initialize_component(\"%s\", \"%s\", FALSE);\n",
503 ct_mod->get_modid().get_dispname().c_str(), ct_dispname_str);
504 }
505 }
506 }
507 if (has_base_comps) {
508 // closing of the if() above
509 target->functions.init_comp = mputstr(target->functions.init_comp,
510 "}\n");
511 }
512 }
513
514 // code generation for embedded definitions
515 size_t nof_defs = def_v.size();
516 for (size_t i = 0; i < nof_defs; i++) {
517 Ttcn::Definition *def = def_v[i];
518 const string& name = def->get_id().get_name();
519 if (orig_defs_m.has_key(name)) {
520 // def is hidden by an inherited definiton
521 // only an initializer shall be generated
522 target->functions.init_comp = def->generate_code_init_comp(
523 target->functions.init_comp, all_defs_m[name]);
524 } else {
525 // def is a normal (non-inherited) definition
526 def->generate_code(target, true);
527 }
528 }
529
530 // end of block in init_comp
531 target->functions.init_comp = mputstr(target->functions.init_comp,
532 "return TRUE;\n"
533 "} else ");
534 }
535
536 char *ComponentTypeBody::generate_code_comptype_name(char *str)
537 {
538 if (!comp_id)
539 FATAL_ERROR("ComponentTypeBody::generate_code_comtype_name()");
540 return mputprintf(str, "\"%s\", \"%s\"",
541 parent_scope->get_scope_mod_gen()->get_modid().get_dispname().c_str(),
542 comp_id->get_dispname().c_str());
543 }
544
545 void ComponentTypeBody::set_parent_path(Ttcn::WithAttribPath* p_path) {
546 for (size_t i = 0; i < def_v.size(); i++)
547 def_v[i]->set_parent_path(p_path);
548 }
549
550 // =================================
551 // ===== CompTypeRefList
552 // =================================
553
554 CompTypeRefList::~CompTypeRefList()
555 {
556 for (size_t i=0; i<comp_ref_v.size(); i++) delete comp_ref_v[i];
557 comp_ref_v.clear();
558 comp_body_m.clear();
559 comp_body_v.clear();
560 }
561
562 CompTypeRefList *CompTypeRefList::clone() const
563 {
564 FATAL_ERROR("CompTypeRefList::clone()");
565 }
566
567 void CompTypeRefList::add_ref(Ttcn::Reference *p_ref)
568 {
569 if (!p_ref || checked) FATAL_ERROR("CompTypeRefList::add_ref()");
570 comp_ref_v.add(p_ref);
571 }
572
573 void CompTypeRefList::dump(unsigned level) const
574 {
575 for(size_t i = 0; i < comp_ref_v.size(); i++) comp_ref_v[i]->dump(level+1);
576 }
577
578 void CompTypeRefList::set_fullname(const string& p_fullname)
579 {
580 Node::set_fullname(p_fullname);
581 for (size_t i=0; i<comp_ref_v.size(); i++)
582 comp_ref_v[i]->set_fullname(p_fullname + ".<ref" + Int2string(i+1) + ">");
583 }
584
585 void CompTypeRefList::chk_uniq()
586 {
587 if (checked) return;
588 checked = true;
589 for (size_t i = 0; i < comp_ref_v.size(); i++)
590 {
591 Ttcn::Reference *ref = comp_ref_v[i];
592 Type *type = ref->chk_comptype_ref();
593 if (type)
594 {
595 // add the component body to the map or error if it's duplicate
596 ComponentTypeBody *cb = type->get_CompBody();
597 if (cb)
598 {
599 if (comp_body_m.has_key(cb))
600 {
601 const string& type_name = type->get_typename();
602 const char *name = type_name.c_str();
603 ref->error("Duplicate reference to component with name `%s'", name);
604 comp_body_m[cb]->note("Previous reference to `%s' is here", name);
605 }
606 else
607 {
608 // map and vector must always have same content
609 comp_body_m.add(cb, ref);
610 comp_body_v.add(cb);
611 }
612 }
613 }
614 }
615 }
616
617 void CompTypeRefList::chk(ComponentTypeBody::check_state_t
618 required_check_state)
619 {
620 chk_uniq();
621 for (size_t i=0; i<comp_body_v.size(); i++)
622 comp_body_v[i]->chk(required_check_state);
623 }
624
625 void CompTypeRefList::chk_recursion(ReferenceChain& refch)
626 {
627 for (size_t i = 0; i < comp_body_v.size(); i++) {
628 refch.mark_state();
629 comp_body_v[i]->chk_recursion(refch);
630 refch.prev_state();
631 }
632 }
633
634 void CompTypeRefList::set_my_scope(Scope *p_scope)
635 {
636 for (size_t i=0; i<comp_ref_v.size(); i++)
637 comp_ref_v[i]->set_my_scope(p_scope);
638 }
639
640 size_t CompTypeRefList::get_nof_comps()
641 {
642 if (!checked) chk_uniq();
643 return comp_body_v.size();
644 }
645
646 ComponentTypeBody *CompTypeRefList::get_nth_comp_body(size_t i)
647 {
648 if (!checked) chk_uniq();
649 return comp_body_v[i];
650 }
651
652 Ttcn::Reference *CompTypeRefList::get_nth_comp_ref(size_t i)
653 {
654 if (!checked) chk_uniq();
655 return comp_body_m[comp_body_v[i]];
656 }
657
658 bool CompTypeRefList::has_comp_body(ComponentTypeBody *cb)
659 {
660 if (!checked) chk_uniq();
661 return comp_body_m.has_key(cb);
662 }
663
664 } /* namespace Common */
This page took 0.045498 seconds and 5 git commands to generate.