Titan Core Initial Contribution
[deliverable/titan.core.git] / compiler2 / ttcn3 / Templatestuff.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 "../../common/dbgnew.hh"
9 #include "Templatestuff.hh"
10 #include "../Identifier.hh"
11 #include "TtcnTemplate.hh"
12 #include "ArrayDimensions.hh"
13
14 #include <limits.h>
15
16 namespace Ttcn {
17
18 // =================================
19 // ===== ValueRange
20 // =================================
21
22 ValueRange::~ValueRange()
23 {
24 delete min_v;
25 delete max_v;
26 }
27
28 ValueRange *ValueRange::clone() const
29 {
30 return new ValueRange(*this);
31 }
32
33 ValueRange::ValueRange(const ValueRange& other)
34 : Node(other)
35 , min_v(other.min_v ? other.min_v->clone() : 0)
36 , max_v(other.max_v ? other.max_v->clone() : 0)
37 {}
38
39 void ValueRange::set_fullname(const string& p_fullname)
40 {
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>");
44 }
45
46 void ValueRange::set_my_scope(Scope *p_scope)
47 {
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);
51 }
52
53 void ValueRange::set_lowerid_to_ref()
54 {
55 if (min_v) min_v->set_lowerid_to_ref();
56 if (max_v) max_v->set_lowerid_to_ref();
57 }
58
59 Type::typetype_t ValueRange::get_expr_returntype(
60 Type::expected_value_t exp_val)
61 {
62 if (min_v) {
63 Type::typetype_t tt = min_v->get_expr_returntype(exp_val);
64 if (tt != Type::T_UNDEF) return tt;
65 }
66 if (max_v) {
67 Type::typetype_t tt = max_v->get_expr_returntype(exp_val);
68 if (tt != Type::T_UNDEF) return tt;
69 }
70 return Type::T_UNDEF;
71 }
72
73 Type *ValueRange::get_expr_governor(Type::expected_value_t exp_val)
74 {
75 if (min_v) {
76 Type *t = min_v->get_expr_governor(exp_val);
77 if (t) return t;
78 }
79 if (max_v) {
80 Type *t = max_v->get_expr_governor(exp_val);
81 if (t) return t;
82 }
83 return 0;
84 }
85
86 void ValueRange::set_code_section
87 (GovernedSimple::code_section_t p_code_section)
88 {
89 if (min_v) min_v->set_code_section(p_code_section);
90 if (max_v) max_v->set_code_section(p_code_section);
91 }
92
93 char *ValueRange::generate_code_init(char *str, const char *name)
94 {
95 expression_struct expr;
96 Code::init_expr(&expr);
97 char *init_stmt = mprintf("%s.set_type(VALUE_RANGE);\n", name);
98 if (min_v) {
99 min_v->generate_code_expr(&expr);
100 init_stmt = mputprintf(init_stmt, "%s.set_min(%s);\n", name, expr.expr);
101 }
102 if (max_v) {
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);
106 }
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);
115 Free(init_stmt);
116 return str;
117 }
118
119 char *ValueRange::rearrange_init_code(char *str)
120 {
121 if (min_v) str = min_v->rearrange_init_code(str);
122 if (max_v) str = max_v->rearrange_init_code(str);
123 return str;
124 }
125
126 void ValueRange::append_stringRepr(string& str) const
127 {
128 str += "(";
129 if (min_v) str += min_v->get_stringRepr();
130 else str += "-infinity";
131 str += " .. ";
132 if (max_v) str += max_v->get_stringRepr();
133 else str += "infinity";
134 str += ")";
135 }
136
137 void ValueRange::dump(unsigned level) const
138 {
139 DEBUG(level, "(");
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");
145 DEBUG(level, ")");
146 }
147
148 // =================================
149 // ===== Templates
150 // =================================
151
152 Templates::~Templates()
153 {
154 for (size_t i = 0; i < ts.size(); i++) delete ts[i];
155 ts.clear();
156 }
157
158 Templates::Templates(const Templates& other)
159 : Node(), ts()
160 {
161 for (size_t i = 0, lim = other.ts.size(); i < lim; ++i) {
162 ts.add(other.ts[i]->clone());
163 }
164 }
165
166 Templates *Templates::clone() const
167 {
168 return new Templates(*this);
169 }
170
171 void Templates::set_my_scope(Scope *p_scope)
172 {
173 for (size_t i = 0; i < ts.size(); i++) ts[i]->set_my_scope(p_scope);
174 }
175
176 void Templates::add_t(Template *p_t)
177 {
178 if (!p_t) FATAL_ERROR("NULL pointer:Templates::add_t()");
179 ts.add(p_t);
180 }
181
182 void Templates::add_front_t(Template *p_t)
183 {
184 if (!p_t) FATAL_ERROR("NULL pointer:Templates::add_front_t()");
185 ts.add_front(p_t);
186 }
187
188 void Templates::append_stringRepr(string& str) const
189 {
190 for (size_t i = 0; i < ts.size(); i++) {
191 if (i > 0) str += ", ";
192 str += ts[i]->get_stringRepr();
193 }
194 }
195
196 // =================================
197 // ===== IndexedTemplate
198 // =================================
199
200 IndexedTemplate::IndexedTemplate(FieldOrArrayRef *p_i, Template *p_t)
201 {
202 if (!p_i || !p_t) FATAL_ERROR("IndexedTemplate::IndexedTemplate()");
203 index = p_i;
204 temp = p_t;
205 }
206
207 IndexedTemplate::~IndexedTemplate()
208 {
209 delete index;
210 delete temp;
211 }
212
213 IndexedTemplate *IndexedTemplate::clone() const
214 {
215 FATAL_ERROR("IndexedTemplate::clone");
216 }
217
218 void IndexedTemplate::set_fullname(const string& p_fullname)
219 {
220 Node::set_fullname(p_fullname);
221 temp->set_fullname(p_fullname);
222 index->set_fullname(p_fullname);
223 }
224
225 void IndexedTemplate::set_my_scope(Scope *p_scope)
226 {
227 Node::set_my_scope(p_scope);
228 temp->set_my_scope(p_scope);
229 index->set_my_scope(p_scope);
230 }
231
232 void IndexedTemplate::set_code_section
233 (GovernedSimple::code_section_t p_code_section)
234 {
235 index->get_val()->set_code_section(p_code_section);
236 temp->set_code_section(p_code_section);
237 }
238
239 void IndexedTemplate::dump(unsigned level) const
240 {
241 index->dump(level);
242 temp->dump(level);
243 }
244
245 // =================================
246 // ===== IndexedTemplates
247 // =================================
248
249 IndexedTemplates::~IndexedTemplates()
250 {
251 for (size_t i = 0; i < its_v.size(); i++) delete its_v[i];
252 its_v.clear();
253 }
254
255 IndexedTemplates *IndexedTemplates::clone() const
256 {
257 FATAL_ERROR("IndexedTemplates::clone");
258 }
259
260 void IndexedTemplates::set_fullname(const string& p_fullname)
261 {
262 Node::set_fullname(p_fullname);
263 for(size_t i = 0; i < its_v.size(); i++) {
264 IndexedTemplate *it = its_v[i];
265 string t_fullname = p_fullname;
266 (it->get_index()).append_stringRepr(t_fullname);
267 it->set_fullname(t_fullname);
268 }
269 }
270
271 void IndexedTemplates::set_my_scope(Scope *p_scope)
272 {
273 Node::set_my_scope(p_scope);
274 for (size_t i = 0; i < its_v.size(); i++)
275 its_v[i]->set_my_scope(p_scope);
276 }
277
278 void IndexedTemplates::add_it(IndexedTemplate *p_it)
279 {
280 if (!p_it) FATAL_ERROR("NULL pointer: IndexedTemplates::add_it()");
281 its_v.add(p_it);
282 }
283
284 IndexedTemplate *IndexedTemplates::get_it_byIndex(size_t p_i)
285 {
286 return its_v[p_i];
287 }
288
289 // =================================
290 // ===== NamedTemplate
291 // =================================
292
293 NamedTemplate::NamedTemplate(Identifier *p_n, Template *p_t)
294 {
295 if (!p_n || !p_t) FATAL_ERROR("NamedTemplate::NamedTemplate()");
296 name = p_n;
297 temp = p_t;
298 }
299
300 NamedTemplate::~NamedTemplate()
301 {
302 delete name;
303 delete temp;
304 }
305
306 NamedTemplate *NamedTemplate::clone() const
307 {
308 FATAL_ERROR("NamedTemplate::clone");
309 }
310
311 void NamedTemplate::set_fullname(const string& p_fullname)
312 {
313 Node::set_fullname(p_fullname);
314 temp->set_fullname(p_fullname);
315 }
316
317 void NamedTemplate::set_my_scope(Scope *p_scope)
318 {
319 Node::set_my_scope(p_scope);
320 temp->set_my_scope(p_scope);
321 }
322
323 Template* NamedTemplate::extract_template()
324 {
325 Template * ret = temp;
326 temp = 0;
327 return ret;
328 }
329
330 void NamedTemplate::dump(unsigned level) const
331 {
332 name->dump(level);
333 temp->dump(level);
334 }
335
336 // =================================
337 // ===== NamedTemplates
338 // =================================
339
340 NamedTemplates::~NamedTemplates()
341 {
342 for (size_t i = 0; i < nts_v.size(); i++) delete nts_v[i];
343 nts_v.clear();
344 nts_m.clear();
345 }
346
347 NamedTemplates *NamedTemplates::clone() const
348 {
349 FATAL_ERROR("NamedTemplates::clone");
350 }
351
352 void NamedTemplates::set_fullname(const string& p_fullname)
353 {
354 Node::set_fullname(p_fullname);
355 for(size_t i = 0; i < nts_v.size(); i++) {
356 NamedTemplate *nt = nts_v[i];
357 nt->set_fullname(p_fullname + "." + nt->get_name().get_dispname());
358 }
359 }
360
361 void NamedTemplates::set_my_scope(Scope *p_scope)
362 {
363 Node::set_my_scope(p_scope);
364 for(size_t i = 0; i < nts_v.size(); i++) nts_v[i]->set_my_scope(p_scope);
365 }
366
367 void NamedTemplates::add_nt(NamedTemplate *p_nt)
368 {
369 if (!p_nt) FATAL_ERROR("NULL pointer:NamedTemplates::add_nt()");
370 nts_v.add(p_nt);
371 if (checked) {
372 const string& name = p_nt->get_name().get_name();
373 if (!nts_m.has_key(name)) nts_m.add(name, p_nt);
374 }
375 }
376
377 bool NamedTemplates::has_nt_withName(const Identifier& p_name)
378 {
379 if (!checked) chk_dupl_id(false);
380 return nts_m.has_key(p_name.get_name());
381 }
382
383 NamedTemplate *NamedTemplates::get_nt_byName(const Identifier& p_name)
384 {
385 if (!checked) chk_dupl_id(false);
386 return nts_m[p_name.get_name()];
387 }
388
389 void NamedTemplates::chk_dupl_id(bool report_errors)
390 {
391 if (checked) nts_m.clear();
392 for (size_t i = 0; i < nts_v.size(); i++) {
393 NamedTemplate *nt = nts_v[i];
394 const Identifier& id = nt->get_name();
395 const string& name = id.get_name();
396 if (!nts_m.has_key(name)) nts_m.add(name, nt);
397 else if (report_errors) {
398 const char *disp_name = id.get_dispname().c_str();
399 nt->error("Duplicate field name `%s'", disp_name);
400 nts_m[name]->note("Field `%s' is already given here", disp_name);
401 }
402 }
403 checked = true;
404 }
405
406 // =================================
407 // ===== LengthRestriction
408 // =================================
409
410 LengthRestriction::LengthRestriction(Value* p_val)
411 : Node(), checked(false), is_range(false)
412 {
413 if (!p_val)
414 FATAL_ERROR("LengthRestriction::LengthRestriction()");
415 single = p_val;
416 }
417
418 LengthRestriction::LengthRestriction(Value* p_lower, Value* p_upper)
419 : Node(), checked(false), is_range(true)
420 {
421 if (!p_lower)
422 FATAL_ERROR("LengthRestriction::LengthRestriction()");
423 range.lower = p_lower;
424 range.upper = p_upper;
425 }
426
427 LengthRestriction::~LengthRestriction()
428 {
429 if (is_range) {
430 delete range.lower;
431 delete range.upper;
432 } else delete single;
433 }
434
435 LengthRestriction *LengthRestriction::clone() const
436 {
437 FATAL_ERROR("LengthRestriction::clone");
438 }
439
440 void LengthRestriction::set_fullname(const string& p_fullname)
441 {
442 Node::set_fullname(p_fullname);
443 if (is_range) {
444 range.lower->set_fullname(p_fullname + ".<lower>");
445 if (range.upper) range.upper->set_fullname(p_fullname + ".<upper>");
446 } else single->set_fullname(p_fullname);
447 }
448
449 void LengthRestriction::set_my_scope(Scope *p_scope)
450 {
451 if (is_range) {
452 range.lower->set_my_scope(p_scope);
453 if (range.upper) range.upper->set_my_scope(p_scope);
454 } else single->set_my_scope(p_scope);
455 }
456
457 void LengthRestriction::chk(Type::expected_value_t expected_value)
458 {
459 if (checked) return;
460 checked = true;
461 Type *pool_int = Type::get_pooltype(Type::T_INT);
462 if (is_range) {
463 range.lower->set_my_governor(pool_int);
464 {
465 Error_Context cntxt(range.lower, "In lower boundary of the length "
466 "restriction");
467 pool_int->chk_this_value_ref(range.lower);
468 pool_int->chk_this_value(range.lower, 0, expected_value,
469 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
470 }
471 Value *v_lower = range.lower->get_value_refd_last();
472 int_val_t v_int_lower_int;
473 if (v_lower->get_valuetype() == Value::V_INT) {
474 v_int_lower_int = *(v_lower->get_val_Int());
475 if (v_int_lower_int < 0) {
476 range.lower->error("The lower boundary of the length restriction "
477 "must be a non-negative integer value instead of %s",
478 v_int_lower_int.t_str().c_str());
479 range.lower->set_valuetype(Value::V_ERROR);
480 v_int_lower_int = int_val_t((Int)0);
481 }
482 } else {
483 v_int_lower_int = int_val_t((Int)0);
484 }
485 if (range.upper) {
486 range.upper->set_my_governor(pool_int);
487 {
488 Error_Context cntxt(range.lower, "In upper boundary of the length "
489 "restriction");
490 pool_int->chk_this_value_ref(range.upper);
491 pool_int->chk_this_value(range.upper, 0, expected_value,
492 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
493 }
494 Value *v_upper = range.upper->get_value_refd_last();
495 if (v_upper->get_valuetype() == Value::V_INT) {
496 int_val_t v_int_upper_int(*(v_upper->get_val_Int()));
497 if (v_int_upper_int < 0) {
498 range.upper->error("The upper boundary of the length "
499 "restriction must be a non-negative integer value instead "
500 "of %s", v_int_upper_int.t_str().c_str());
501 range.upper->set_valuetype(Value::V_ERROR);
502 } else if (v_int_upper_int < v_int_lower_int) {
503 error("The upper boundary of the length restriction (%s) "
504 "cannot be smaller than the lower boundary (%s)",
505 v_int_upper_int.t_str().c_str(),
506 v_int_lower_int.t_str().c_str());
507 range.upper->set_valuetype(Value::V_ERROR);
508 }
509 }
510 }
511 } else {
512 single->set_my_governor(pool_int);
513 {
514 Error_Context cntxt(single, "In length restriction");
515 pool_int->chk_this_value_ref(single);
516 pool_int->chk_this_value(single, 0, expected_value,
517 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
518 }
519 Value *v_single = single->get_value_refd_last();
520 if (v_single->get_valuetype() == Value::V_INT) {
521 const int_val_t *v_int_int = v_single->get_val_Int();
522 if (*v_int_int < 0) {
523 single->error("The length restriction must be a non-negative "
524 "integer value instead of %s", (v_int_int->t_str()).c_str());
525 single->set_valuetype(Value::V_ERROR);
526 }
527 }
528 }
529 }
530
531 void LengthRestriction::chk_array_size(ArrayDimension *p_dim)
532 {
533 if (!checked) FATAL_ERROR("LengthRestriction::chk_array_size()");
534 bool error_flag = false;
535 if (!p_dim->get_has_error()) {
536 size_t array_size = p_dim->get_size();
537 if (is_range) {
538 Value *v_lower_last = range.lower->get_value_refd_last();
539 if (v_lower_last->get_valuetype() == Value::V_INT) {
540 const int_val_t *lower_len_int = v_lower_last->get_val_Int();
541 if (*lower_len_int > INT_MAX) {
542 range.lower->error("An integer value less than `%d' was expected "
543 "as the lower boundary of the length restriction instead of "
544 "`%s'", INT_MAX, (lower_len_int->t_str()).c_str());
545 error_flag = true;
546 } else {
547 Int lower_len = lower_len_int->get_val();
548 if (lower_len > static_cast<Int>(array_size)) {
549 range.lower->error("The number of elements allowed by the "
550 "length restriction (at least %s) contradicts the array size "
551 "(%lu)", Int2string(lower_len).c_str(),
552 (unsigned long)array_size);
553 error_flag = true;
554 }
555 }
556 }
557 if (range.upper) {
558 Value *v_upper_last = range.upper->get_value_refd_last();
559 if (v_upper_last->get_valuetype() == Value::V_INT) {
560 const int_val_t *upper_len_int = v_upper_last->get_val_Int();
561 if (*upper_len_int > INT_MAX) {
562 range.upper->error("An integer value less than `%d' was "
563 "expected as the upper boundary of the length restriction "
564 "instead of `%s'", INT_MAX, (upper_len_int->t_str()).c_str());
565 error_flag = true;
566 } else {
567 Int upper_len = upper_len_int->get_val();
568 if (upper_len < static_cast<Int>(array_size)) {
569 range.upper->error("The number of elements allowed by the "
570 "length restriction (at most %s) contradicts the array "
571 "size (%lu)", Int2string(upper_len).c_str(),
572 (unsigned long)array_size);
573 error_flag = true;
574 }
575 }
576 }
577 }
578 } else {
579 Value *v_last = single->get_value_refd_last();
580 if (v_last->get_valuetype() == Value::V_INT) {
581 int_val_t single_len_int(*(v_last->get_val_Int()));
582 if (single_len_int != static_cast<Int>(array_size)) {
583 single->error("The number of elements allowed by the length "
584 "restriction (%s) contradicts the array size (%lu)",
585 single_len_int.t_str().c_str(), (unsigned long)array_size);
586 error_flag = true;
587 }
588 }
589 }
590 }
591 if (!error_flag)
592 warning("Length restriction is useless for an array template");
593 }
594
595 void LengthRestriction::chk_nof_elements(size_t nof_elements,
596 bool has_anyornone, const Location& p_loc, const char *p_what)
597 {
598 if (!checked) FATAL_ERROR("LengthRestriction::chk_nof_elements()");
599 if (is_range) {
600 if (!has_anyornone) {
601 Value *v_lower_last = range.lower->get_value_refd_last();
602 if (v_lower_last->get_valuetype() == Value::V_INT) {
603 const int_val_t *lower_len_int = v_lower_last->get_val_Int();
604 if (*lower_len_int > static_cast<Int>(nof_elements)) {
605 p_loc.error("There are fewer (%lu) elements in the %s than it "
606 "is allowed by the length restriction (at least %s)",
607 (unsigned long)nof_elements, p_what,
608 (lower_len_int->t_str()).c_str());
609 }
610 }
611 }
612 if (range.upper) {
613 Value *v_upper_last = range.upper->get_value_refd_last();
614 if (v_upper_last->get_valuetype() == Value::V_INT) {
615 const int_val_t *upper_len_int = v_upper_last->get_val_Int();
616 if (*upper_len_int < static_cast<Int>(nof_elements)) {
617 p_loc.error("There are more (%s%lu) elements in the %s than it "
618 "is allowed by the length restriction (at most %s)",
619 has_anyornone ? "at least " : "", (unsigned long)nof_elements,
620 p_what, (upper_len_int->t_str()).c_str());
621 }
622 }
623 }
624 } else {
625 Value *v_last = single->get_value_refd_last();
626 if (v_last->get_valuetype() == Value::V_INT) {
627 // Cheaper than creating a local variable?
628 const int_val_t *single_len_int = v_last->get_val_Int();
629 if (*single_len_int < static_cast<Int>(nof_elements)) {
630 p_loc.error("There are more (%s%lu) elements in the %s than it "
631 "is allowed by the length restriction (%s)", has_anyornone ?
632 "at least " : "", (unsigned long)nof_elements, p_what,
633 (single_len_int->t_str()).c_str());
634 } else if (*single_len_int > static_cast<Int>(nof_elements) &&
635 !has_anyornone) {
636 p_loc.error("There are fewer (%lu) elements in the %s than it "
637 "is allowed by the length restriction (%s)",
638 (unsigned long)nof_elements, p_what,
639 (single_len_int->t_str()).c_str());
640 }
641 }
642 }
643 }
644
645 Value* LengthRestriction::get_single_value()
646 {
647 if (is_range) FATAL_ERROR("LengthRestriction::get_single_value()");
648 if (!checked) FATAL_ERROR("LengthRestriction::get_single_value()");
649 return single->get_value_refd_last();
650 }
651
652 Value *LengthRestriction::get_lower_value()
653 {
654 if (!is_range) FATAL_ERROR("LengthRestriction::get_lower_value()");
655 if (!checked) FATAL_ERROR("LengthRestriction::get_lower_value()");
656 return range.lower->get_value_refd_last();
657 }
658
659 Value *LengthRestriction::get_upper_value()
660 {
661 if (!is_range) FATAL_ERROR("LengthRestriction::get_upper_value()");
662 if (!checked) FATAL_ERROR("LengthRestriction::get_upper_value()");
663 return range.upper ? range.upper->get_value_refd_last() : 0;
664 }
665
666 void LengthRestriction::set_code_section
667 (GovernedSimple::code_section_t p_code_section)
668 {
669 if (is_range) {
670 range.lower->set_code_section(p_code_section);
671 if (range.upper) range.upper->set_code_section(p_code_section);
672 } else single->set_code_section(p_code_section);
673 }
674
675 char *LengthRestriction::generate_code_init(char *str, const char *name)
676 {
677 expression_struct expr;
678 Code::init_expr(&expr);
679 char *init_stmt;
680 if (is_range) {
681 range.lower->generate_code_expr(&expr);
682 init_stmt = mprintf("%s.set_min_length(%s);\n", name, expr.expr);
683 if (range.upper) {
684 Code::clean_expr(&expr);
685 range.upper->generate_code_expr(&expr);
686 init_stmt = mputprintf(init_stmt, "%s.set_max_length(%s);\n", name,
687 expr.expr);
688 }
689 } else {
690 single->generate_code_expr(&expr);
691 init_stmt = mprintf("%s.set_single_length(%s);\n", name, expr.expr);
692 }
693 if (expr.preamble || expr.postamble) {
694 str = mputstr(str, "{\n");
695 str = mputstr(str, expr.preamble);
696 str = mputstr(str, init_stmt);
697 str = mputstr(str, expr.postamble);
698 str = mputstr(str, "}\n");
699 } else str = mputstr(str, init_stmt);
700 Code::free_expr(&expr);
701 Free(init_stmt);
702 return str;
703 }
704
705 char *LengthRestriction::rearrange_init_code(char *str)
706 {
707 if (is_range) {
708 str = range.lower->rearrange_init_code(str);
709 if (range.upper) str = range.upper->rearrange_init_code(str);
710 } else str = single->rearrange_init_code(str);
711 return str;
712 }
713
714 void LengthRestriction::append_stringRepr(string& str) const
715 {
716 str += "length(";
717 if (is_range) {
718 str += range.lower->get_stringRepr();
719 str += " .. ";
720 if (range.upper) str += range.upper->get_stringRepr();
721 else str += "infinity";
722 } else str += single->get_stringRepr();
723 str += ")";
724 }
725
726 void LengthRestriction::dump(unsigned level) const
727 {
728 DEBUG(level, "length restriction:");
729 if (is_range) {
730 range.lower->dump(level + 1);
731 DEBUG(level, "..");
732 if (range.upper) range.upper->dump(level + 1);
733 else DEBUG(level + 1, "infinity");
734 } else single->dump(level + 1);
735 }
736
737 // =================================
738 // ===== TemplateInstances
739 // =================================
740
741 TemplateInstances::TemplateInstances(const TemplateInstances& p)
742 : Node(p), Location(p), tis()
743 {
744 for (size_t i = 0; i < p.tis.size(); i++)
745 tis.add(p.tis[i]->clone());
746 }
747
748 TemplateInstances::~TemplateInstances()
749 {
750 for (size_t i = 0; i < tis.size(); i++) delete tis[i];
751 tis.clear();
752 }
753
754 TemplateInstances *TemplateInstances::clone() const
755 {
756 return new TemplateInstances(*this);
757 }
758
759 void TemplateInstances::set_fullname(const string& p_fullname)
760 {
761 Node::set_fullname(p_fullname);
762 for (size_t i = 0; i < tis.size(); i++)
763 tis[i]->set_fullname(p_fullname + "[" + Int2string(i + 1) + "]");
764 }
765
766 void TemplateInstances::set_my_scope(Scope *p_scope)
767 {
768 for (size_t i = 0; i < tis.size(); i++)
769 {
770 TemplateInstance*& tir = tis[i];
771 tir->set_my_scope(p_scope);
772 }
773 }
774
775 void TemplateInstances::add_ti(TemplateInstance *p_ti)
776 {
777 if (!p_ti) FATAL_ERROR("NULL pointer:TemplateInstances::add_ti()");
778 tis.add(p_ti);
779 }
780
781 void TemplateInstances::set_code_section
782 (GovernedSimple::code_section_t p_code_section)
783 {
784 for (size_t i=0; i<tis.size(); i++)
785 tis[i]->set_code_section(p_code_section);
786 }
787
788 void TemplateInstances::dump(unsigned level) const
789 {
790 DEBUG(level, "TemplateInstances %p, has %lu", (const void*)this,
791 (unsigned long) tis.size());
792 for (size_t i = 0; i < tis.size(); ++i) {
793 tis[i]->dump(level+1);
794 }
795 }
796 // =================================
797 // ===== NamedParam
798 // =================================
799
800 NamedParam::NamedParam(Identifier *id, TemplateInstance *t)
801 : Node(), Location(), name(id), tmpl(t)
802 {
803 }
804
805 NamedParam::NamedParam(const NamedParam& p)
806 : Node(p), Location(p), name(p.name->clone()), tmpl(p.tmpl->clone())
807 {
808 }
809
810 NamedParam::~NamedParam()
811 {
812 delete tmpl;
813 delete name;
814 }
815
816 NamedParam * NamedParam::clone() const {
817 return new NamedParam(*this);
818 }
819
820 void NamedParam::set_my_scope(Scope *p_scope)
821 {
822 tmpl->set_my_scope(p_scope);
823 }
824
825 void NamedParam::set_fullname(const string& p_fullname)
826 {
827 Node::set_fullname(p_fullname);
828 tmpl->set_fullname(p_fullname);
829 }
830
831 TemplateInstance * NamedParam::extract_ti()
832 {
833 TemplateInstance *retval = tmpl;
834 tmpl = 0;
835 return retval;
836 }
837
838 void NamedParam::dump(unsigned int level) const
839 {
840 name->dump(level+1);
841 tmpl->dump(level+1);
842 }
843 // =================================
844 // ===== NamedParams
845 // =================================
846
847 NamedParams::NamedParams()
848 : Node(), Location(), nps()
849 {
850 }
851
852 NamedParams * NamedParams::clone() const
853 {
854 FATAL_ERROR("NamedParams::clone");
855 }
856
857 NamedParams::~NamedParams()
858 {
859 for (size_t i = 0; i < nps.size(); i++) delete nps[i];
860 nps.clear();
861 }
862
863 void NamedParams::set_my_scope(Scope *p_scope)
864 {
865 for (size_t i = 0; i < nps.size(); i++) nps[i]->set_my_scope(p_scope);
866 }
867
868 void NamedParams::set_fullname(const string& p_fullname)
869 {
870 for (size_t i = 0; i < nps.size(); i++) nps[i]->set_fullname(p_fullname);
871 }
872
873 void NamedParams::add_np(NamedParam *p)
874 {
875 if (!p) FATAL_ERROR("NULL pointer: NamedParams::add_np()");
876 nps.add(p);
877 }
878
879 size_t NamedParams::get_nof_nps() const
880 {
881 return nps.size();
882 }
883
884 NamedParam *NamedParams::extract_np_byIndex(size_t p_i)
885 {
886 NamedParam * retval = nps[p_i];
887 nps[p_i] = 0;
888 return retval;
889 }
890
891 void NamedParams::dump(unsigned int level) const
892 {
893 DEBUG(level, "NamedParams %p, has %lu", (const void*)this,
894 (unsigned long) nps.size());
895 for (unsigned int i = 0; i < nps.size(); ++i) {
896 if (nps[i] != 0) {
897 nps[i]->dump(level+1);
898 } else {
899 DEBUG(level+1, "NULL");
900 }
901 }
902 }
903 // =================================
904 // ===== ParsedActualParameters
905 // =================================
906
907 ParsedActualParameters::ParsedActualParameters(TemplateInstances *p_ti,
908 NamedParams *p_np)
909 : Node(), Location(), unnamedpart(p_ti ? p_ti : new TemplateInstances), namedpart(p_np)
910 {
911 }
912
913 ParsedActualParameters::ParsedActualParameters(const ParsedActualParameters& p)
914 : Node(p), Location(p), unnamedpart(p.unnamedpart->clone()),
915 namedpart (p.namedpart ? p.namedpart->clone() : 0)
916 {
917 }
918
919 ParsedActualParameters* ParsedActualParameters::clone() const
920 {
921 return new ParsedActualParameters(*this);
922 }
923
924 ParsedActualParameters::~ParsedActualParameters()
925 {
926 delete namedpart;
927 delete unnamedpart;
928 }
929
930 void ParsedActualParameters::add_np(NamedParam *np)
931 {
932 if (!namedpart) // we got away without one until now
933 {
934 namedpart = new NamedParams;
935 }
936 namedpart->add_np(np);
937 }
938
939 TemplateInstances* ParsedActualParameters::steal_tis()
940 {
941 TemplateInstances* temp = unnamedpart;
942 unnamedpart = new TemplateInstances;
943 return temp;
944 }
945
946 size_t ParsedActualParameters::get_nof_nps() const
947 {
948 return namedpart ? namedpart->get_nof_nps() : 0;
949 }
950
951 void ParsedActualParameters::set_my_scope(Common::Scope *p_scope)
952 {
953 unnamedpart->set_my_scope(p_scope);
954 if (namedpart) {
955 namedpart->set_my_scope(p_scope);
956 }
957 }
958
959 void ParsedActualParameters::set_fullname(const string& p_fullname)
960 {
961 unnamedpart->set_fullname(p_fullname);
962 if (namedpart) {
963 namedpart->set_fullname(p_fullname);
964 }
965 }
966
967 void ParsedActualParameters::set_location(const char *p_filename, int p_lineno)
968 {
969 Location ::set_location(p_filename, p_lineno);
970 if (namedpart)
971 namedpart->set_location(p_filename, p_lineno);
972 unnamedpart->set_location(p_filename, p_lineno);
973 }
974
975 void ParsedActualParameters::set_location(const char *p_filename,
976 const YYLTYPE& p_yyloc)
977 {
978 Location ::set_location(p_filename, p_yyloc);
979 if (namedpart)
980 namedpart->set_location(p_filename, p_yyloc);
981 unnamedpart->set_location(p_filename, p_yyloc);
982 }
983
984 void ParsedActualParameters::set_location(const char *p_filename,
985 const YYLTYPE& p_firstloc,
986 const YYLTYPE & p_lastloc)
987 {
988 Location ::set_location(p_filename, p_firstloc, p_lastloc);
989 if (namedpart)
990 namedpart->set_location(p_filename, p_firstloc, p_lastloc);
991 unnamedpart->set_location(p_filename, p_firstloc, p_lastloc);
992 }
993
994 void ParsedActualParameters::set_location(const char *p_filename, int p_first_line,
995 int p_first_column, int p_last_line, int p_last_column)
996 {
997 Location ::set_location(p_filename, p_first_line, p_first_column,
998 p_last_line, p_last_column);
999 if (namedpart)
1000 namedpart->set_location(p_filename, p_first_line, p_first_column,
1001 p_last_line, p_last_column);
1002 unnamedpart->set_location(p_filename, p_first_line, p_first_column,
1003 p_last_line, p_last_column);
1004 }
1005
1006
1007 void ParsedActualParameters::dump(unsigned int level) const
1008 {
1009 DEBUG(level, "ParsedActualParameters at %p", (const void*)this);
1010 unnamedpart->dump(level+1);
1011 if (namedpart) {
1012 namedpart->dump(level+1);
1013 }
1014 }
1015 }
This page took 0.052793 seconds and 6 git commands to generate.