1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 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 "../../common/dbgnew.hh"
9 #include "Templatestuff.hh"
10 #include "../Identifier.hh"
11 #include "TtcnTemplate.hh"
12 #include "ArrayDimensions.hh"
18 // =================================
20 // =================================
22 ValueRange::~ValueRange()
28 ValueRange
*ValueRange::clone() const
30 return new ValueRange(*this);
33 ValueRange::ValueRange(const ValueRange
& other
)
35 , min_v(other
.min_v
? other
.min_v
->clone() : 0)
36 , max_v(other
.max_v
? other
.max_v
->clone() : 0)
39 void ValueRange::set_fullname(const string
& p_fullname
)
41 Node::set_fullname(p_fullname
);
42 if (min_v
) min_v
->set_fullname(p_fullname
+ ".<lower_bound>");
43 if (max_v
) max_v
->set_fullname(p_fullname
+ ".<upper_bound>");
46 void ValueRange::set_my_scope(Scope
*p_scope
)
48 Node::set_my_scope(p_scope
);
49 if (min_v
) min_v
->set_my_scope(p_scope
);
50 if (max_v
) max_v
->set_my_scope(p_scope
);
53 void ValueRange::set_lowerid_to_ref()
55 if (min_v
) min_v
->set_lowerid_to_ref();
56 if (max_v
) max_v
->set_lowerid_to_ref();
59 Type::typetype_t
ValueRange::get_expr_returntype(
60 Type::expected_value_t exp_val
)
63 Type::typetype_t tt
= min_v
->get_expr_returntype(exp_val
);
64 if (tt
!= Type::T_UNDEF
) return tt
;
67 Type::typetype_t tt
= max_v
->get_expr_returntype(exp_val
);
68 if (tt
!= Type::T_UNDEF
) return tt
;
73 Type
*ValueRange::get_expr_governor(Type::expected_value_t exp_val
)
76 Type
*t
= min_v
->get_expr_governor(exp_val
);
80 Type
*t
= max_v
->get_expr_governor(exp_val
);
86 void ValueRange::set_code_section
87 (GovernedSimple::code_section_t p_code_section
)
89 if (min_v
) min_v
->set_code_section(p_code_section
);
90 if (max_v
) max_v
->set_code_section(p_code_section
);
93 char *ValueRange::generate_code_init(char *str
, const char *name
)
95 expression_struct expr
;
96 Code::init_expr(&expr
);
97 char *init_stmt
= mprintf("%s.set_type(VALUE_RANGE);\n", name
);
99 min_v
->generate_code_expr(&expr
);
100 init_stmt
= mputprintf(init_stmt
, "%s.set_min(%s);\n", name
, expr
.expr
);
103 Code::clean_expr(&expr
);
104 max_v
->generate_code_expr(&expr
);
105 init_stmt
= mputprintf(init_stmt
, "%s.set_max(%s);\n", name
, expr
.expr
);
107 if (expr
.preamble
|| expr
.postamble
) {
108 str
= mputstr(str
, "{\n");
109 str
= mputstr(str
, expr
.preamble
);
110 str
= mputstr(str
, init_stmt
);
111 str
= mputstr(str
, expr
.postamble
);
112 str
= mputstr(str
, "}\n");
113 } else str
= mputstr(str
, init_stmt
);
114 Code::free_expr(&expr
);
119 char *ValueRange::rearrange_init_code(char *str
)
121 if (min_v
) str
= min_v
->rearrange_init_code(str
);
122 if (max_v
) str
= max_v
->rearrange_init_code(str
);
126 void ValueRange::append_stringRepr(string
& str
) const
129 if (min_v
) str
+= min_v
->get_stringRepr();
130 else str
+= "-infinity";
132 if (max_v
) str
+= max_v
->get_stringRepr();
133 else str
+= "infinity";
137 void ValueRange::dump(unsigned level
) const
140 if (min_v
) min_v
->dump(level
+ 1);
141 else DEBUG(level
+ 1, "-infinity");
142 DEBUG(level
+ 1, "..");
143 if (max_v
) max_v
->dump(level
+ 1);
144 else DEBUG(level
+ 1, "infinity");
148 // =================================
150 // =================================
152 Templates::~Templates()
154 for (size_t i
= 0; i
< ts
.size(); i
++) delete ts
[i
];
158 Templates::Templates(const Templates
& other
)
161 for (size_t i
= 0, lim
= other
.ts
.size(); i
< lim
; ++i
) {
162 ts
.add(other
.ts
[i
]->clone());
166 Templates
*Templates::clone() const
168 return new Templates(*this);
171 void Templates::set_my_scope(Scope
*p_scope
)
173 for (size_t i
= 0; i
< ts
.size(); i
++) ts
[i
]->set_my_scope(p_scope
);
176 void Templates::add_t(Template
*p_t
)
178 if (!p_t
) FATAL_ERROR("NULL pointer:Templates::add_t()");
182 void Templates::add_front_t(Template
*p_t
)
184 if (!p_t
) FATAL_ERROR("NULL pointer:Templates::add_front_t()");
188 void Templates::append_stringRepr(string
& str
) const
190 for (size_t i
= 0; i
< ts
.size(); i
++) {
191 if (i
> 0) str
+= ", ";
192 str
+= ts
[i
]->get_stringRepr();
196 // =================================
197 // ===== IndexedTemplate
198 // =================================
200 IndexedTemplate::IndexedTemplate(const IndexedTemplate
& p
)
202 index
= p
.index
->clone();
203 temp
= p
.temp
->clone();
206 IndexedTemplate::IndexedTemplate(FieldOrArrayRef
*p_i
, Template
*p_t
)
208 if (!p_i
|| !p_t
) FATAL_ERROR("IndexedTemplate::IndexedTemplate()");
213 IndexedTemplate::~IndexedTemplate()
219 IndexedTemplate
*IndexedTemplate::clone() const
221 return new IndexedTemplate(*this);
224 void IndexedTemplate::set_fullname(const string
& p_fullname
)
226 Node::set_fullname(p_fullname
);
227 temp
->set_fullname(p_fullname
);
228 index
->set_fullname(p_fullname
);
231 void IndexedTemplate::set_my_scope(Scope
*p_scope
)
233 Node::set_my_scope(p_scope
);
234 temp
->set_my_scope(p_scope
);
235 index
->set_my_scope(p_scope
);
238 void IndexedTemplate::set_code_section
239 (GovernedSimple::code_section_t p_code_section
)
241 index
->get_val()->set_code_section(p_code_section
);
242 temp
->set_code_section(p_code_section
);
245 void IndexedTemplate::dump(unsigned level
) const
251 // =================================
252 // ===== IndexedTemplates
253 // =================================
255 IndexedTemplates::IndexedTemplates(const IndexedTemplates
& p
)
258 for (size_t i
= 0; i
< p
.its_v
.size(); i
++) {
259 its_v
.add(p
.its_v
[i
]->clone());
263 IndexedTemplates::~IndexedTemplates()
265 for (size_t i
= 0; i
< its_v
.size(); i
++) delete its_v
[i
];
269 IndexedTemplates
*IndexedTemplates::clone() const
271 return new IndexedTemplates(*this);
274 void IndexedTemplates::set_fullname(const string
& p_fullname
)
276 Node::set_fullname(p_fullname
);
277 for(size_t i
= 0; i
< its_v
.size(); i
++) {
278 IndexedTemplate
*it
= its_v
[i
];
279 string t_fullname
= p_fullname
;
280 (it
->get_index()).append_stringRepr(t_fullname
);
281 it
->set_fullname(t_fullname
);
285 void IndexedTemplates::set_my_scope(Scope
*p_scope
)
287 Node::set_my_scope(p_scope
);
288 for (size_t i
= 0; i
< its_v
.size(); i
++)
289 its_v
[i
]->set_my_scope(p_scope
);
292 void IndexedTemplates::add_it(IndexedTemplate
*p_it
)
294 if (!p_it
) FATAL_ERROR("NULL pointer: IndexedTemplates::add_it()");
298 IndexedTemplate
*IndexedTemplates::get_it_byIndex(size_t p_i
)
303 // =================================
304 // ===== NamedTemplate
305 // =================================
307 NamedTemplate::NamedTemplate(Identifier
*p_n
, Template
*p_t
)
309 if (!p_n
|| !p_t
) FATAL_ERROR("NamedTemplate::NamedTemplate()");
314 NamedTemplate::NamedTemplate(const NamedTemplate
& p
)
316 name
= p
.name
->clone();
317 temp
= p
.temp
->clone();
320 NamedTemplate::~NamedTemplate()
326 NamedTemplate
*NamedTemplate::clone() const
328 return new NamedTemplate(*this);
331 void NamedTemplate::set_fullname(const string
& p_fullname
)
333 Node::set_fullname(p_fullname
);
334 temp
->set_fullname(p_fullname
);
337 void NamedTemplate::set_my_scope(Scope
*p_scope
)
339 Node::set_my_scope(p_scope
);
340 temp
->set_my_scope(p_scope
);
343 void NamedTemplate::set_name_to_lowercase()
345 string new_name
= name
->get_name();
346 if (isupper(new_name
[0])) {
347 new_name
[0] = tolower(new_name
[0]);
348 if (new_name
[new_name
.size() - 1] == '_') {
349 // an underscore is inserted at the end of the alternative name if it's
350 // a basic type's name (since it would conflict with the class generated
352 // remove the underscore, it won't conflict with anything if its name
353 // starts with a lowercase letter
354 new_name
.replace(new_name
.size() - 1, 1, "");
357 name
= new Identifier(Identifier::ID_NAME
, new_name
);
361 Template
* NamedTemplate::extract_template()
363 Template
* ret
= temp
;
368 void NamedTemplate::dump(unsigned level
) const
374 // =================================
375 // ===== NamedTemplates
376 // =================================
378 NamedTemplates::NamedTemplates(const NamedTemplates
& p
)
379 : Node(p
), checked(p
.checked
)
381 for (size_t i
= 0; i
< p
.nts_v
.size(); i
++) {
382 NamedTemplate
* nt
= p
.nts_v
[i
]->clone();
385 nts_m
.add(p
.nts_m
.get_nth_key(i
), nt
);
390 NamedTemplates::~NamedTemplates()
392 for (size_t i
= 0; i
< nts_v
.size(); i
++) delete nts_v
[i
];
397 NamedTemplates
*NamedTemplates::clone() const
399 return new NamedTemplates(*this);
402 void NamedTemplates::set_fullname(const string
& p_fullname
)
404 Node::set_fullname(p_fullname
);
405 for(size_t i
= 0; i
< nts_v
.size(); i
++) {
406 NamedTemplate
*nt
= nts_v
[i
];
407 nt
->set_fullname(p_fullname
+ "." + nt
->get_name().get_dispname());
411 void NamedTemplates::set_my_scope(Scope
*p_scope
)
413 Node::set_my_scope(p_scope
);
414 for(size_t i
= 0; i
< nts_v
.size(); i
++) nts_v
[i
]->set_my_scope(p_scope
);
417 void NamedTemplates::add_nt(NamedTemplate
*p_nt
)
419 if (!p_nt
) FATAL_ERROR("NULL pointer:NamedTemplates::add_nt()");
422 const string
& name
= p_nt
->get_name().get_name();
423 if (!nts_m
.has_key(name
)) nts_m
.add(name
, p_nt
);
427 bool NamedTemplates::has_nt_withName(const Identifier
& p_name
)
429 if (!checked
) chk_dupl_id(false);
430 return nts_m
.has_key(p_name
.get_name());
433 NamedTemplate
*NamedTemplates::get_nt_byName(const Identifier
& p_name
)
435 if (!checked
) chk_dupl_id(false);
436 return nts_m
[p_name
.get_name()];
439 void NamedTemplates::chk_dupl_id(bool report_errors
)
441 if (checked
) nts_m
.clear();
442 for (size_t i
= 0; i
< nts_v
.size(); i
++) {
443 NamedTemplate
*nt
= nts_v
[i
];
444 const Identifier
& id
= nt
->get_name();
445 const string
& name
= id
.get_name();
446 if (!nts_m
.has_key(name
)) nts_m
.add(name
, nt
);
447 else if (report_errors
) {
448 const char *disp_name
= id
.get_dispname().c_str();
449 nt
->error("Duplicate field name `%s'", disp_name
);
450 nts_m
[name
]->note("Field `%s' is already given here", disp_name
);
456 // =================================
457 // ===== LengthRestriction
458 // =================================
460 LengthRestriction::LengthRestriction(Value
* p_val
)
461 : Node(), checked(false), is_range(false)
464 FATAL_ERROR("LengthRestriction::LengthRestriction()");
468 LengthRestriction::LengthRestriction(Value
* p_lower
, Value
* p_upper
)
469 : Node(), checked(false), is_range(true)
472 FATAL_ERROR("LengthRestriction::LengthRestriction()");
473 range
.lower
= p_lower
;
474 range
.upper
= p_upper
;
477 LengthRestriction::~LengthRestriction()
482 } else delete single
;
485 LengthRestriction
*LengthRestriction::clone() const
487 FATAL_ERROR("LengthRestriction::clone");
490 void LengthRestriction::set_fullname(const string
& p_fullname
)
492 Node::set_fullname(p_fullname
);
494 range
.lower
->set_fullname(p_fullname
+ ".<lower>");
495 if (range
.upper
) range
.upper
->set_fullname(p_fullname
+ ".<upper>");
496 } else single
->set_fullname(p_fullname
);
499 void LengthRestriction::set_my_scope(Scope
*p_scope
)
502 range
.lower
->set_my_scope(p_scope
);
503 if (range
.upper
) range
.upper
->set_my_scope(p_scope
);
504 } else single
->set_my_scope(p_scope
);
507 void LengthRestriction::chk(Type::expected_value_t expected_value
)
511 Type
*pool_int
= Type::get_pooltype(Type::T_INT
);
513 range
.lower
->set_my_governor(pool_int
);
515 Error_Context
cntxt(range
.lower
, "In lower boundary of the length "
517 pool_int
->chk_this_value_ref(range
.lower
);
518 pool_int
->chk_this_value(range
.lower
, 0, expected_value
,
519 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
521 Value
*v_lower
= range
.lower
->get_value_refd_last();
522 int_val_t v_int_lower_int
;
523 if (v_lower
->get_valuetype() == Value::V_INT
) {
524 v_int_lower_int
= *(v_lower
->get_val_Int());
525 if (v_int_lower_int
< 0) {
526 range
.lower
->error("The lower boundary of the length restriction "
527 "must be a non-negative integer value instead of %s",
528 v_int_lower_int
.t_str().c_str());
529 range
.lower
->set_valuetype(Value::V_ERROR
);
530 v_int_lower_int
= int_val_t((Int
)0);
533 v_int_lower_int
= int_val_t((Int
)0);
536 range
.upper
->set_my_governor(pool_int
);
538 Error_Context
cntxt(range
.lower
, "In upper boundary of the length "
540 pool_int
->chk_this_value_ref(range
.upper
);
541 pool_int
->chk_this_value(range
.upper
, 0, expected_value
,
542 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
544 Value
*v_upper
= range
.upper
->get_value_refd_last();
545 if (v_upper
->get_valuetype() == Value::V_INT
) {
546 int_val_t
v_int_upper_int(*(v_upper
->get_val_Int()));
547 if (v_int_upper_int
< 0) {
548 range
.upper
->error("The upper boundary of the length "
549 "restriction must be a non-negative integer value instead "
550 "of %s", v_int_upper_int
.t_str().c_str());
551 range
.upper
->set_valuetype(Value::V_ERROR
);
552 } else if (v_int_upper_int
< v_int_lower_int
) {
553 error("The upper boundary of the length restriction (%s) "
554 "cannot be smaller than the lower boundary (%s)",
555 v_int_upper_int
.t_str().c_str(),
556 v_int_lower_int
.t_str().c_str());
557 range
.upper
->set_valuetype(Value::V_ERROR
);
562 single
->set_my_governor(pool_int
);
564 Error_Context
cntxt(single
, "In length restriction");
565 pool_int
->chk_this_value_ref(single
);
566 pool_int
->chk_this_value(single
, 0, expected_value
,
567 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
569 Value
*v_single
= single
->get_value_refd_last();
570 if (v_single
->get_valuetype() == Value::V_INT
) {
571 const int_val_t
*v_int_int
= v_single
->get_val_Int();
572 if (*v_int_int
< 0) {
573 single
->error("The length restriction must be a non-negative "
574 "integer value instead of %s", (v_int_int
->t_str()).c_str());
575 single
->set_valuetype(Value::V_ERROR
);
581 void LengthRestriction::chk_array_size(ArrayDimension
*p_dim
)
583 if (!checked
) FATAL_ERROR("LengthRestriction::chk_array_size()");
584 bool error_flag
= false;
585 if (!p_dim
->get_has_error()) {
586 size_t array_size
= p_dim
->get_size();
588 Value
*v_lower_last
= range
.lower
->get_value_refd_last();
589 if (v_lower_last
->get_valuetype() == Value::V_INT
) {
590 const int_val_t
*lower_len_int
= v_lower_last
->get_val_Int();
591 if (*lower_len_int
> INT_MAX
) {
592 range
.lower
->error("An integer value less than `%d' was expected "
593 "as the lower boundary of the length restriction instead of "
594 "`%s'", INT_MAX
, (lower_len_int
->t_str()).c_str());
597 Int lower_len
= lower_len_int
->get_val();
598 if (lower_len
> static_cast<Int
>(array_size
)) {
599 range
.lower
->error("The number of elements allowed by the "
600 "length restriction (at least %s) contradicts the array size "
601 "(%lu)", Int2string(lower_len
).c_str(),
602 (unsigned long)array_size
);
608 Value
*v_upper_last
= range
.upper
->get_value_refd_last();
609 if (v_upper_last
->get_valuetype() == Value::V_INT
) {
610 const int_val_t
*upper_len_int
= v_upper_last
->get_val_Int();
611 if (*upper_len_int
> INT_MAX
) {
612 range
.upper
->error("An integer value less than `%d' was "
613 "expected as the upper boundary of the length restriction "
614 "instead of `%s'", INT_MAX
, (upper_len_int
->t_str()).c_str());
617 Int upper_len
= upper_len_int
->get_val();
618 if (upper_len
< static_cast<Int
>(array_size
)) {
619 range
.upper
->error("The number of elements allowed by the "
620 "length restriction (at most %s) contradicts the array "
621 "size (%lu)", Int2string(upper_len
).c_str(),
622 (unsigned long)array_size
);
629 Value
*v_last
= single
->get_value_refd_last();
630 if (v_last
->get_valuetype() == Value::V_INT
) {
631 int_val_t
single_len_int(*(v_last
->get_val_Int()));
632 if (single_len_int
!= static_cast<Int
>(array_size
)) {
633 single
->error("The number of elements allowed by the length "
634 "restriction (%s) contradicts the array size (%lu)",
635 single_len_int
.t_str().c_str(), (unsigned long)array_size
);
642 warning("Length restriction is useless for an array template");
645 void LengthRestriction::chk_nof_elements(size_t nof_elements
,
646 bool has_anyornone
, const Location
& p_loc
, const char *p_what
)
648 if (!checked
) FATAL_ERROR("LengthRestriction::chk_nof_elements()");
650 if (!has_anyornone
) {
651 Value
*v_lower_last
= range
.lower
->get_value_refd_last();
652 if (v_lower_last
->get_valuetype() == Value::V_INT
) {
653 const int_val_t
*lower_len_int
= v_lower_last
->get_val_Int();
654 if (*lower_len_int
> static_cast<Int
>(nof_elements
)) {
655 p_loc
.error("There are fewer (%lu) elements in the %s than it "
656 "is allowed by the length restriction (at least %s)",
657 (unsigned long)nof_elements
, p_what
,
658 (lower_len_int
->t_str()).c_str());
663 Value
*v_upper_last
= range
.upper
->get_value_refd_last();
664 if (v_upper_last
->get_valuetype() == Value::V_INT
) {
665 const int_val_t
*upper_len_int
= v_upper_last
->get_val_Int();
666 if (*upper_len_int
< static_cast<Int
>(nof_elements
)) {
667 p_loc
.error("There are more (%s%lu) elements in the %s than it "
668 "is allowed by the length restriction (at most %s)",
669 has_anyornone
? "at least " : "", (unsigned long)nof_elements
,
670 p_what
, (upper_len_int
->t_str()).c_str());
675 Value
*v_last
= single
->get_value_refd_last();
676 if (v_last
->get_valuetype() == Value::V_INT
) {
677 // Cheaper than creating a local variable?
678 const int_val_t
*single_len_int
= v_last
->get_val_Int();
679 if (*single_len_int
< static_cast<Int
>(nof_elements
)) {
680 p_loc
.error("There are more (%s%lu) elements in the %s than it "
681 "is allowed by the length restriction (%s)", has_anyornone
?
682 "at least " : "", (unsigned long)nof_elements
, p_what
,
683 (single_len_int
->t_str()).c_str());
684 } else if (*single_len_int
> static_cast<Int
>(nof_elements
) &&
686 p_loc
.error("There are fewer (%lu) elements in the %s than it "
687 "is allowed by the length restriction (%s)",
688 (unsigned long)nof_elements
, p_what
,
689 (single_len_int
->t_str()).c_str());
695 Value
* LengthRestriction::get_single_value()
697 if (is_range
) FATAL_ERROR("LengthRestriction::get_single_value()");
698 if (!checked
) FATAL_ERROR("LengthRestriction::get_single_value()");
699 return single
->get_value_refd_last();
702 Value
*LengthRestriction::get_lower_value()
704 if (!is_range
) FATAL_ERROR("LengthRestriction::get_lower_value()");
705 if (!checked
) FATAL_ERROR("LengthRestriction::get_lower_value()");
706 return range
.lower
->get_value_refd_last();
709 Value
*LengthRestriction::get_upper_value()
711 if (!is_range
) FATAL_ERROR("LengthRestriction::get_upper_value()");
712 if (!checked
) FATAL_ERROR("LengthRestriction::get_upper_value()");
713 return range
.upper
? range
.upper
->get_value_refd_last() : 0;
716 void LengthRestriction::set_code_section
717 (GovernedSimple::code_section_t p_code_section
)
720 range
.lower
->set_code_section(p_code_section
);
721 if (range
.upper
) range
.upper
->set_code_section(p_code_section
);
722 } else single
->set_code_section(p_code_section
);
725 char *LengthRestriction::generate_code_init(char *str
, const char *name
)
727 expression_struct expr
;
728 Code::init_expr(&expr
);
731 range
.lower
->generate_code_expr(&expr
);
732 init_stmt
= mprintf("%s.set_min_length(%s);\n", name
, expr
.expr
);
734 Code::clean_expr(&expr
);
735 range
.upper
->generate_code_expr(&expr
);
736 init_stmt
= mputprintf(init_stmt
, "%s.set_max_length(%s);\n", name
,
740 single
->generate_code_expr(&expr
);
741 init_stmt
= mprintf("%s.set_single_length(%s);\n", name
, expr
.expr
);
743 if (expr
.preamble
|| expr
.postamble
) {
744 str
= mputstr(str
, "{\n");
745 str
= mputstr(str
, expr
.preamble
);
746 str
= mputstr(str
, init_stmt
);
747 str
= mputstr(str
, expr
.postamble
);
748 str
= mputstr(str
, "}\n");
749 } else str
= mputstr(str
, init_stmt
);
750 Code::free_expr(&expr
);
755 char *LengthRestriction::rearrange_init_code(char *str
)
758 str
= range
.lower
->rearrange_init_code(str
);
759 if (range
.upper
) str
= range
.upper
->rearrange_init_code(str
);
760 } else str
= single
->rearrange_init_code(str
);
764 void LengthRestriction::append_stringRepr(string
& str
) const
768 str
+= range
.lower
->get_stringRepr();
770 if (range
.upper
) str
+= range
.upper
->get_stringRepr();
771 else str
+= "infinity";
772 } else str
+= single
->get_stringRepr();
776 void LengthRestriction::dump(unsigned level
) const
778 DEBUG(level
, "length restriction:");
780 range
.lower
->dump(level
+ 1);
782 if (range
.upper
) range
.upper
->dump(level
+ 1);
783 else DEBUG(level
+ 1, "infinity");
784 } else single
->dump(level
+ 1);
787 // =================================
788 // ===== TemplateInstances
789 // =================================
791 TemplateInstances::TemplateInstances(const TemplateInstances
& p
)
792 : Node(p
), Location(p
), tis()
794 for (size_t i
= 0; i
< p
.tis
.size(); i
++)
795 tis
.add(p
.tis
[i
]->clone());
798 TemplateInstances::~TemplateInstances()
800 for (size_t i
= 0; i
< tis
.size(); i
++) delete tis
[i
];
804 TemplateInstances
*TemplateInstances::clone() const
806 return new TemplateInstances(*this);
809 void TemplateInstances::set_fullname(const string
& p_fullname
)
811 Node::set_fullname(p_fullname
);
812 for (size_t i
= 0; i
< tis
.size(); i
++)
813 tis
[i
]->set_fullname(p_fullname
+ "[" + Int2string(i
+ 1) + "]");
816 void TemplateInstances::set_my_scope(Scope
*p_scope
)
818 for (size_t i
= 0; i
< tis
.size(); i
++)
820 TemplateInstance
*& tir
= tis
[i
];
821 tir
->set_my_scope(p_scope
);
825 void TemplateInstances::add_ti(TemplateInstance
*p_ti
)
827 if (!p_ti
) FATAL_ERROR("NULL pointer:TemplateInstances::add_ti()");
831 void TemplateInstances::set_code_section
832 (GovernedSimple::code_section_t p_code_section
)
834 for (size_t i
=0; i
<tis
.size(); i
++)
835 tis
[i
]->set_code_section(p_code_section
);
838 void TemplateInstances::dump(unsigned level
) const
840 DEBUG(level
, "TemplateInstances %p, has %lu", (const void*)this,
841 (unsigned long) tis
.size());
842 for (size_t i
= 0; i
< tis
.size(); ++i
) {
843 tis
[i
]->dump(level
+1);
846 // =================================
848 // =================================
850 NamedParam::NamedParam(Identifier
*id
, TemplateInstance
*t
)
851 : Node(), Location(), name(id
), tmpl(t
)
855 NamedParam::NamedParam(const NamedParam
& p
)
856 : Node(p
), Location(p
), name(p
.name
->clone()), tmpl(p
.tmpl
->clone())
860 NamedParam::~NamedParam()
866 NamedParam
* NamedParam::clone() const {
867 return new NamedParam(*this);
870 void NamedParam::set_my_scope(Scope
*p_scope
)
872 tmpl
->set_my_scope(p_scope
);
875 void NamedParam::set_fullname(const string
& p_fullname
)
877 Node::set_fullname(p_fullname
);
878 tmpl
->set_fullname(p_fullname
);
881 TemplateInstance
* NamedParam::extract_ti()
883 TemplateInstance
*retval
= tmpl
;
888 void NamedParam::dump(unsigned int level
) const
893 // =================================
895 // =================================
897 NamedParams::NamedParams()
898 : Node(), Location(), nps()
902 NamedParams
* NamedParams::clone() const
904 FATAL_ERROR("NamedParams::clone");
907 NamedParams::~NamedParams()
909 for (size_t i
= 0; i
< nps
.size(); i
++) delete nps
[i
];
913 void NamedParams::set_my_scope(Scope
*p_scope
)
915 for (size_t i
= 0; i
< nps
.size(); i
++) nps
[i
]->set_my_scope(p_scope
);
918 void NamedParams::set_fullname(const string
& p_fullname
)
920 for (size_t i
= 0; i
< nps
.size(); i
++) nps
[i
]->set_fullname(p_fullname
);
923 void NamedParams::add_np(NamedParam
*p
)
925 if (!p
) FATAL_ERROR("NULL pointer: NamedParams::add_np()");
929 size_t NamedParams::get_nof_nps() const
934 NamedParam
*NamedParams::extract_np_byIndex(size_t p_i
)
936 NamedParam
* retval
= nps
[p_i
];
941 void NamedParams::dump(unsigned int level
) const
943 DEBUG(level
, "NamedParams %p, has %lu", (const void*)this,
944 (unsigned long) nps
.size());
945 for (unsigned int i
= 0; i
< nps
.size(); ++i
) {
947 nps
[i
]->dump(level
+1);
949 DEBUG(level
+1, "NULL");
953 // =================================
954 // ===== ParsedActualParameters
955 // =================================
957 ParsedActualParameters::ParsedActualParameters(TemplateInstances
*p_ti
,
959 : Node(), Location(), unnamedpart(p_ti
? p_ti
: new TemplateInstances
), namedpart(p_np
)
963 ParsedActualParameters::ParsedActualParameters(const ParsedActualParameters
& p
)
964 : Node(p
), Location(p
), unnamedpart(p
.unnamedpart
->clone()),
965 namedpart (p
.namedpart
? p
.namedpart
->clone() : 0)
969 ParsedActualParameters
* ParsedActualParameters::clone() const
971 return new ParsedActualParameters(*this);
974 ParsedActualParameters::~ParsedActualParameters()
980 void ParsedActualParameters::add_np(NamedParam
*np
)
982 if (!namedpart
) // we got away without one until now
984 namedpart
= new NamedParams
;
986 namedpart
->add_np(np
);
989 TemplateInstances
* ParsedActualParameters::steal_tis()
991 TemplateInstances
* temp
= unnamedpart
;
992 unnamedpart
= new TemplateInstances
;
996 size_t ParsedActualParameters::get_nof_nps() const
998 return namedpart
? namedpart
->get_nof_nps() : 0;
1001 void ParsedActualParameters::set_my_scope(Common::Scope
*p_scope
)
1003 unnamedpart
->set_my_scope(p_scope
);
1005 namedpart
->set_my_scope(p_scope
);
1009 void ParsedActualParameters::set_fullname(const string
& p_fullname
)
1011 unnamedpart
->set_fullname(p_fullname
);
1013 namedpart
->set_fullname(p_fullname
);
1017 void ParsedActualParameters::set_location(const char *p_filename
, int p_lineno
)
1019 Location ::set_location(p_filename
, p_lineno
);
1021 namedpart
->set_location(p_filename
, p_lineno
);
1022 unnamedpart
->set_location(p_filename
, p_lineno
);
1025 void ParsedActualParameters::set_location(const char *p_filename
,
1026 const YYLTYPE
& p_yyloc
)
1028 Location ::set_location(p_filename
, p_yyloc
);
1030 namedpart
->set_location(p_filename
, p_yyloc
);
1031 unnamedpart
->set_location(p_filename
, p_yyloc
);
1034 void ParsedActualParameters::set_location(const char *p_filename
,
1035 const YYLTYPE
& p_firstloc
,
1036 const YYLTYPE
& p_lastloc
)
1038 Location ::set_location(p_filename
, p_firstloc
, p_lastloc
);
1040 namedpart
->set_location(p_filename
, p_firstloc
, p_lastloc
);
1041 unnamedpart
->set_location(p_filename
, p_firstloc
, p_lastloc
);
1044 void ParsedActualParameters::set_location(const char *p_filename
, int p_first_line
,
1045 int p_first_column
, int p_last_line
, int p_last_column
)
1047 Location ::set_location(p_filename
, p_first_line
, p_first_column
,
1048 p_last_line
, p_last_column
);
1050 namedpart
->set_location(p_filename
, p_first_line
, p_first_column
,
1051 p_last_line
, p_last_column
);
1052 unnamedpart
->set_location(p_filename
, p_first_line
, p_first_column
,
1053 p_last_line
, p_last_column
);
1057 void ParsedActualParameters::dump(unsigned int level
) const
1059 DEBUG(level
, "ParsedActualParameters at %p", (const void*)this);
1060 unnamedpart
->dump(level
+1);
1062 namedpart
->dump(level
+1);