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