Sync with 5.4.0
[deliverable/titan.core.git] / compiler2 / ttcn3 / Templatestuff.cc
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"
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 void NamedTemplate::set_name_to_lowercase()
324 {
325 string new_name = name->get_name();
326 if (isupper(new_name[0])) {
327 new_name[0] = tolower(new_name[0]);
328 if (new_name[new_name.size() - 1] == '_') {
329 // an underscore is inserted at the end of the alternative name if it's
330 // a basic type's name (since it would conflict with the class generated
331 // for that type)
332 // remove the underscore, it won't conflict with anything if its name
333 // starts with a lowercase letter
334 new_name.replace(new_name.size() - 1, 1, "");
335 }
336 delete name;
337 name = new Identifier(Identifier::ID_NAME, new_name);
338 }
339 }
340
341 Template* NamedTemplate::extract_template()
342 {
343 Template * ret = temp;
344 temp = 0;
345 return ret;
346 }
347
348 void NamedTemplate::dump(unsigned level) const
349 {
350 name->dump(level);
351 temp->dump(level);
352 }
353
354 // =================================
355 // ===== NamedTemplates
356 // =================================
357
358 NamedTemplates::~NamedTemplates()
359 {
360 for (size_t i = 0; i < nts_v.size(); i++) delete nts_v[i];
361 nts_v.clear();
362 nts_m.clear();
363 }
364
365 NamedTemplates *NamedTemplates::clone() const
366 {
367 FATAL_ERROR("NamedTemplates::clone");
368 }
369
370 void NamedTemplates::set_fullname(const string& p_fullname)
371 {
372 Node::set_fullname(p_fullname);
373 for(size_t i = 0; i < nts_v.size(); i++) {
374 NamedTemplate *nt = nts_v[i];
375 nt->set_fullname(p_fullname + "." + nt->get_name().get_dispname());
376 }
377 }
378
379 void NamedTemplates::set_my_scope(Scope *p_scope)
380 {
381 Node::set_my_scope(p_scope);
382 for(size_t i = 0; i < nts_v.size(); i++) nts_v[i]->set_my_scope(p_scope);
383 }
384
385 void NamedTemplates::add_nt(NamedTemplate *p_nt)
386 {
387 if (!p_nt) FATAL_ERROR("NULL pointer:NamedTemplates::add_nt()");
388 nts_v.add(p_nt);
389 if (checked) {
390 const string& name = p_nt->get_name().get_name();
391 if (!nts_m.has_key(name)) nts_m.add(name, p_nt);
392 }
393 }
394
395 bool NamedTemplates::has_nt_withName(const Identifier& p_name)
396 {
397 if (!checked) chk_dupl_id(false);
398 return nts_m.has_key(p_name.get_name());
399 }
400
401 NamedTemplate *NamedTemplates::get_nt_byName(const Identifier& p_name)
402 {
403 if (!checked) chk_dupl_id(false);
404 return nts_m[p_name.get_name()];
405 }
406
407 void NamedTemplates::chk_dupl_id(bool report_errors)
408 {
409 if (checked) nts_m.clear();
410 for (size_t i = 0; i < nts_v.size(); i++) {
411 NamedTemplate *nt = nts_v[i];
412 const Identifier& id = nt->get_name();
413 const string& name = id.get_name();
414 if (!nts_m.has_key(name)) nts_m.add(name, nt);
415 else if (report_errors) {
416 const char *disp_name = id.get_dispname().c_str();
417 nt->error("Duplicate field name `%s'", disp_name);
418 nts_m[name]->note("Field `%s' is already given here", disp_name);
419 }
420 }
421 checked = true;
422 }
423
424 // =================================
425 // ===== LengthRestriction
426 // =================================
427
428 LengthRestriction::LengthRestriction(Value* p_val)
429 : Node(), checked(false), is_range(false)
430 {
431 if (!p_val)
432 FATAL_ERROR("LengthRestriction::LengthRestriction()");
433 single = p_val;
434 }
435
436 LengthRestriction::LengthRestriction(Value* p_lower, Value* p_upper)
437 : Node(), checked(false), is_range(true)
438 {
439 if (!p_lower)
440 FATAL_ERROR("LengthRestriction::LengthRestriction()");
441 range.lower = p_lower;
442 range.upper = p_upper;
443 }
444
445 LengthRestriction::~LengthRestriction()
446 {
447 if (is_range) {
448 delete range.lower;
449 delete range.upper;
450 } else delete single;
451 }
452
453 LengthRestriction *LengthRestriction::clone() const
454 {
455 FATAL_ERROR("LengthRestriction::clone");
456 }
457
458 void LengthRestriction::set_fullname(const string& p_fullname)
459 {
460 Node::set_fullname(p_fullname);
461 if (is_range) {
462 range.lower->set_fullname(p_fullname + ".<lower>");
463 if (range.upper) range.upper->set_fullname(p_fullname + ".<upper>");
464 } else single->set_fullname(p_fullname);
465 }
466
467 void LengthRestriction::set_my_scope(Scope *p_scope)
468 {
469 if (is_range) {
470 range.lower->set_my_scope(p_scope);
471 if (range.upper) range.upper->set_my_scope(p_scope);
472 } else single->set_my_scope(p_scope);
473 }
474
475 void LengthRestriction::chk(Type::expected_value_t expected_value)
476 {
477 if (checked) return;
478 checked = true;
479 Type *pool_int = Type::get_pooltype(Type::T_INT);
480 if (is_range) {
481 range.lower->set_my_governor(pool_int);
482 {
483 Error_Context cntxt(range.lower, "In lower boundary of the length "
484 "restriction");
485 pool_int->chk_this_value_ref(range.lower);
486 pool_int->chk_this_value(range.lower, 0, expected_value,
487 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
488 }
489 Value *v_lower = range.lower->get_value_refd_last();
490 int_val_t v_int_lower_int;
491 if (v_lower->get_valuetype() == Value::V_INT) {
492 v_int_lower_int = *(v_lower->get_val_Int());
493 if (v_int_lower_int < 0) {
494 range.lower->error("The lower boundary of the length restriction "
495 "must be a non-negative integer value instead of %s",
496 v_int_lower_int.t_str().c_str());
497 range.lower->set_valuetype(Value::V_ERROR);
498 v_int_lower_int = int_val_t((Int)0);
499 }
500 } else {
501 v_int_lower_int = int_val_t((Int)0);
502 }
503 if (range.upper) {
504 range.upper->set_my_governor(pool_int);
505 {
506 Error_Context cntxt(range.lower, "In upper boundary of the length "
507 "restriction");
508 pool_int->chk_this_value_ref(range.upper);
509 pool_int->chk_this_value(range.upper, 0, expected_value,
510 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
511 }
512 Value *v_upper = range.upper->get_value_refd_last();
513 if (v_upper->get_valuetype() == Value::V_INT) {
514 int_val_t v_int_upper_int(*(v_upper->get_val_Int()));
515 if (v_int_upper_int < 0) {
516 range.upper->error("The upper boundary of the length "
517 "restriction must be a non-negative integer value instead "
518 "of %s", v_int_upper_int.t_str().c_str());
519 range.upper->set_valuetype(Value::V_ERROR);
520 } else if (v_int_upper_int < v_int_lower_int) {
521 error("The upper boundary of the length restriction (%s) "
522 "cannot be smaller than the lower boundary (%s)",
523 v_int_upper_int.t_str().c_str(),
524 v_int_lower_int.t_str().c_str());
525 range.upper->set_valuetype(Value::V_ERROR);
526 }
527 }
528 }
529 } else {
530 single->set_my_governor(pool_int);
531 {
532 Error_Context cntxt(single, "In length restriction");
533 pool_int->chk_this_value_ref(single);
534 pool_int->chk_this_value(single, 0, expected_value,
535 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK);
536 }
537 Value *v_single = single->get_value_refd_last();
538 if (v_single->get_valuetype() == Value::V_INT) {
539 const int_val_t *v_int_int = v_single->get_val_Int();
540 if (*v_int_int < 0) {
541 single->error("The length restriction must be a non-negative "
542 "integer value instead of %s", (v_int_int->t_str()).c_str());
543 single->set_valuetype(Value::V_ERROR);
544 }
545 }
546 }
547 }
548
549 void LengthRestriction::chk_array_size(ArrayDimension *p_dim)
550 {
551 if (!checked) FATAL_ERROR("LengthRestriction::chk_array_size()");
552 bool error_flag = false;
553 if (!p_dim->get_has_error()) {
554 size_t array_size = p_dim->get_size();
555 if (is_range) {
556 Value *v_lower_last = range.lower->get_value_refd_last();
557 if (v_lower_last->get_valuetype() == Value::V_INT) {
558 const int_val_t *lower_len_int = v_lower_last->get_val_Int();
559 if (*lower_len_int > INT_MAX) {
560 range.lower->error("An integer value less than `%d' was expected "
561 "as the lower boundary of the length restriction instead of "
562 "`%s'", INT_MAX, (lower_len_int->t_str()).c_str());
563 error_flag = true;
564 } else {
565 Int lower_len = lower_len_int->get_val();
566 if (lower_len > static_cast<Int>(array_size)) {
567 range.lower->error("The number of elements allowed by the "
568 "length restriction (at least %s) contradicts the array size "
569 "(%lu)", Int2string(lower_len).c_str(),
570 (unsigned long)array_size);
571 error_flag = true;
572 }
573 }
574 }
575 if (range.upper) {
576 Value *v_upper_last = range.upper->get_value_refd_last();
577 if (v_upper_last->get_valuetype() == Value::V_INT) {
578 const int_val_t *upper_len_int = v_upper_last->get_val_Int();
579 if (*upper_len_int > INT_MAX) {
580 range.upper->error("An integer value less than `%d' was "
581 "expected as the upper boundary of the length restriction "
582 "instead of `%s'", INT_MAX, (upper_len_int->t_str()).c_str());
583 error_flag = true;
584 } else {
585 Int upper_len = upper_len_int->get_val();
586 if (upper_len < static_cast<Int>(array_size)) {
587 range.upper->error("The number of elements allowed by the "
588 "length restriction (at most %s) contradicts the array "
589 "size (%lu)", Int2string(upper_len).c_str(),
590 (unsigned long)array_size);
591 error_flag = true;
592 }
593 }
594 }
595 }
596 } else {
597 Value *v_last = single->get_value_refd_last();
598 if (v_last->get_valuetype() == Value::V_INT) {
599 int_val_t single_len_int(*(v_last->get_val_Int()));
600 if (single_len_int != static_cast<Int>(array_size)) {
601 single->error("The number of elements allowed by the length "
602 "restriction (%s) contradicts the array size (%lu)",
603 single_len_int.t_str().c_str(), (unsigned long)array_size);
604 error_flag = true;
605 }
606 }
607 }
608 }
609 if (!error_flag)
610 warning("Length restriction is useless for an array template");
611 }
612
613 void LengthRestriction::chk_nof_elements(size_t nof_elements,
614 bool has_anyornone, const Location& p_loc, const char *p_what)
615 {
616 if (!checked) FATAL_ERROR("LengthRestriction::chk_nof_elements()");
617 if (is_range) {
618 if (!has_anyornone) {
619 Value *v_lower_last = range.lower->get_value_refd_last();
620 if (v_lower_last->get_valuetype() == Value::V_INT) {
621 const int_val_t *lower_len_int = v_lower_last->get_val_Int();
622 if (*lower_len_int > static_cast<Int>(nof_elements)) {
623 p_loc.error("There are fewer (%lu) elements in the %s than it "
624 "is allowed by the length restriction (at least %s)",
625 (unsigned long)nof_elements, p_what,
626 (lower_len_int->t_str()).c_str());
627 }
628 }
629 }
630 if (range.upper) {
631 Value *v_upper_last = range.upper->get_value_refd_last();
632 if (v_upper_last->get_valuetype() == Value::V_INT) {
633 const int_val_t *upper_len_int = v_upper_last->get_val_Int();
634 if (*upper_len_int < static_cast<Int>(nof_elements)) {
635 p_loc.error("There are more (%s%lu) elements in the %s than it "
636 "is allowed by the length restriction (at most %s)",
637 has_anyornone ? "at least " : "", (unsigned long)nof_elements,
638 p_what, (upper_len_int->t_str()).c_str());
639 }
640 }
641 }
642 } else {
643 Value *v_last = single->get_value_refd_last();
644 if (v_last->get_valuetype() == Value::V_INT) {
645 // Cheaper than creating a local variable?
646 const int_val_t *single_len_int = v_last->get_val_Int();
647 if (*single_len_int < static_cast<Int>(nof_elements)) {
648 p_loc.error("There are more (%s%lu) elements in the %s than it "
649 "is allowed by the length restriction (%s)", has_anyornone ?
650 "at least " : "", (unsigned long)nof_elements, p_what,
651 (single_len_int->t_str()).c_str());
652 } else if (*single_len_int > static_cast<Int>(nof_elements) &&
653 !has_anyornone) {
654 p_loc.error("There are fewer (%lu) elements in the %s than it "
655 "is allowed by the length restriction (%s)",
656 (unsigned long)nof_elements, p_what,
657 (single_len_int->t_str()).c_str());
658 }
659 }
660 }
661 }
662
663 Value* LengthRestriction::get_single_value()
664 {
665 if (is_range) FATAL_ERROR("LengthRestriction::get_single_value()");
666 if (!checked) FATAL_ERROR("LengthRestriction::get_single_value()");
667 return single->get_value_refd_last();
668 }
669
670 Value *LengthRestriction::get_lower_value()
671 {
672 if (!is_range) FATAL_ERROR("LengthRestriction::get_lower_value()");
673 if (!checked) FATAL_ERROR("LengthRestriction::get_lower_value()");
674 return range.lower->get_value_refd_last();
675 }
676
677 Value *LengthRestriction::get_upper_value()
678 {
679 if (!is_range) FATAL_ERROR("LengthRestriction::get_upper_value()");
680 if (!checked) FATAL_ERROR("LengthRestriction::get_upper_value()");
681 return range.upper ? range.upper->get_value_refd_last() : 0;
682 }
683
684 void LengthRestriction::set_code_section
685 (GovernedSimple::code_section_t p_code_section)
686 {
687 if (is_range) {
688 range.lower->set_code_section(p_code_section);
689 if (range.upper) range.upper->set_code_section(p_code_section);
690 } else single->set_code_section(p_code_section);
691 }
692
693 char *LengthRestriction::generate_code_init(char *str, const char *name)
694 {
695 expression_struct expr;
696 Code::init_expr(&expr);
697 char *init_stmt;
698 if (is_range) {
699 range.lower->generate_code_expr(&expr);
700 init_stmt = mprintf("%s.set_min_length(%s);\n", name, expr.expr);
701 if (range.upper) {
702 Code::clean_expr(&expr);
703 range.upper->generate_code_expr(&expr);
704 init_stmt = mputprintf(init_stmt, "%s.set_max_length(%s);\n", name,
705 expr.expr);
706 }
707 } else {
708 single->generate_code_expr(&expr);
709 init_stmt = mprintf("%s.set_single_length(%s);\n", name, expr.expr);
710 }
711 if (expr.preamble || expr.postamble) {
712 str = mputstr(str, "{\n");
713 str = mputstr(str, expr.preamble);
714 str = mputstr(str, init_stmt);
715 str = mputstr(str, expr.postamble);
716 str = mputstr(str, "}\n");
717 } else str = mputstr(str, init_stmt);
718 Code::free_expr(&expr);
719 Free(init_stmt);
720 return str;
721 }
722
723 char *LengthRestriction::rearrange_init_code(char *str)
724 {
725 if (is_range) {
726 str = range.lower->rearrange_init_code(str);
727 if (range.upper) str = range.upper->rearrange_init_code(str);
728 } else str = single->rearrange_init_code(str);
729 return str;
730 }
731
732 void LengthRestriction::append_stringRepr(string& str) const
733 {
734 str += "length(";
735 if (is_range) {
736 str += range.lower->get_stringRepr();
737 str += " .. ";
738 if (range.upper) str += range.upper->get_stringRepr();
739 else str += "infinity";
740 } else str += single->get_stringRepr();
741 str += ")";
742 }
743
744 void LengthRestriction::dump(unsigned level) const
745 {
746 DEBUG(level, "length restriction:");
747 if (is_range) {
748 range.lower->dump(level + 1);
749 DEBUG(level, "..");
750 if (range.upper) range.upper->dump(level + 1);
751 else DEBUG(level + 1, "infinity");
752 } else single->dump(level + 1);
753 }
754
755 // =================================
756 // ===== TemplateInstances
757 // =================================
758
759 TemplateInstances::TemplateInstances(const TemplateInstances& p)
760 : Node(p), Location(p), tis()
761 {
762 for (size_t i = 0; i < p.tis.size(); i++)
763 tis.add(p.tis[i]->clone());
764 }
765
766 TemplateInstances::~TemplateInstances()
767 {
768 for (size_t i = 0; i < tis.size(); i++) delete tis[i];
769 tis.clear();
770 }
771
772 TemplateInstances *TemplateInstances::clone() const
773 {
774 return new TemplateInstances(*this);
775 }
776
777 void TemplateInstances::set_fullname(const string& p_fullname)
778 {
779 Node::set_fullname(p_fullname);
780 for (size_t i = 0; i < tis.size(); i++)
781 tis[i]->set_fullname(p_fullname + "[" + Int2string(i + 1) + "]");
782 }
783
784 void TemplateInstances::set_my_scope(Scope *p_scope)
785 {
786 for (size_t i = 0; i < tis.size(); i++)
787 {
788 TemplateInstance*& tir = tis[i];
789 tir->set_my_scope(p_scope);
790 }
791 }
792
793 void TemplateInstances::add_ti(TemplateInstance *p_ti)
794 {
795 if (!p_ti) FATAL_ERROR("NULL pointer:TemplateInstances::add_ti()");
796 tis.add(p_ti);
797 }
798
799 void TemplateInstances::set_code_section
800 (GovernedSimple::code_section_t p_code_section)
801 {
802 for (size_t i=0; i<tis.size(); i++)
803 tis[i]->set_code_section(p_code_section);
804 }
805
806 void TemplateInstances::dump(unsigned level) const
807 {
808 DEBUG(level, "TemplateInstances %p, has %lu", (const void*)this,
809 (unsigned long) tis.size());
810 for (size_t i = 0; i < tis.size(); ++i) {
811 tis[i]->dump(level+1);
812 }
813 }
814 // =================================
815 // ===== NamedParam
816 // =================================
817
818 NamedParam::NamedParam(Identifier *id, TemplateInstance *t)
819 : Node(), Location(), name(id), tmpl(t)
820 {
821 }
822
823 NamedParam::NamedParam(const NamedParam& p)
824 : Node(p), Location(p), name(p.name->clone()), tmpl(p.tmpl->clone())
825 {
826 }
827
828 NamedParam::~NamedParam()
829 {
830 delete tmpl;
831 delete name;
832 }
833
834 NamedParam * NamedParam::clone() const {
835 return new NamedParam(*this);
836 }
837
838 void NamedParam::set_my_scope(Scope *p_scope)
839 {
840 tmpl->set_my_scope(p_scope);
841 }
842
843 void NamedParam::set_fullname(const string& p_fullname)
844 {
845 Node::set_fullname(p_fullname);
846 tmpl->set_fullname(p_fullname);
847 }
848
849 TemplateInstance * NamedParam::extract_ti()
850 {
851 TemplateInstance *retval = tmpl;
852 tmpl = 0;
853 return retval;
854 }
855
856 void NamedParam::dump(unsigned int level) const
857 {
858 name->dump(level+1);
859 tmpl->dump(level+1);
860 }
861 // =================================
862 // ===== NamedParams
863 // =================================
864
865 NamedParams::NamedParams()
866 : Node(), Location(), nps()
867 {
868 }
869
870 NamedParams * NamedParams::clone() const
871 {
872 FATAL_ERROR("NamedParams::clone");
873 }
874
875 NamedParams::~NamedParams()
876 {
877 for (size_t i = 0; i < nps.size(); i++) delete nps[i];
878 nps.clear();
879 }
880
881 void NamedParams::set_my_scope(Scope *p_scope)
882 {
883 for (size_t i = 0; i < nps.size(); i++) nps[i]->set_my_scope(p_scope);
884 }
885
886 void NamedParams::set_fullname(const string& p_fullname)
887 {
888 for (size_t i = 0; i < nps.size(); i++) nps[i]->set_fullname(p_fullname);
889 }
890
891 void NamedParams::add_np(NamedParam *p)
892 {
893 if (!p) FATAL_ERROR("NULL pointer: NamedParams::add_np()");
894 nps.add(p);
895 }
896
897 size_t NamedParams::get_nof_nps() const
898 {
899 return nps.size();
900 }
901
902 NamedParam *NamedParams::extract_np_byIndex(size_t p_i)
903 {
904 NamedParam * retval = nps[p_i];
905 nps[p_i] = 0;
906 return retval;
907 }
908
909 void NamedParams::dump(unsigned int level) const
910 {
911 DEBUG(level, "NamedParams %p, has %lu", (const void*)this,
912 (unsigned long) nps.size());
913 for (unsigned int i = 0; i < nps.size(); ++i) {
914 if (nps[i] != 0) {
915 nps[i]->dump(level+1);
916 } else {
917 DEBUG(level+1, "NULL");
918 }
919 }
920 }
921 // =================================
922 // ===== ParsedActualParameters
923 // =================================
924
925 ParsedActualParameters::ParsedActualParameters(TemplateInstances *p_ti,
926 NamedParams *p_np)
927 : Node(), Location(), unnamedpart(p_ti ? p_ti : new TemplateInstances), namedpart(p_np)
928 {
929 }
930
931 ParsedActualParameters::ParsedActualParameters(const ParsedActualParameters& p)
932 : Node(p), Location(p), unnamedpart(p.unnamedpart->clone()),
933 namedpart (p.namedpart ? p.namedpart->clone() : 0)
934 {
935 }
936
937 ParsedActualParameters* ParsedActualParameters::clone() const
938 {
939 return new ParsedActualParameters(*this);
940 }
941
942 ParsedActualParameters::~ParsedActualParameters()
943 {
944 delete namedpart;
945 delete unnamedpart;
946 }
947
948 void ParsedActualParameters::add_np(NamedParam *np)
949 {
950 if (!namedpart) // we got away without one until now
951 {
952 namedpart = new NamedParams;
953 }
954 namedpart->add_np(np);
955 }
956
957 TemplateInstances* ParsedActualParameters::steal_tis()
958 {
959 TemplateInstances* temp = unnamedpart;
960 unnamedpart = new TemplateInstances;
961 return temp;
962 }
963
964 size_t ParsedActualParameters::get_nof_nps() const
965 {
966 return namedpart ? namedpart->get_nof_nps() : 0;
967 }
968
969 void ParsedActualParameters::set_my_scope(Common::Scope *p_scope)
970 {
971 unnamedpart->set_my_scope(p_scope);
972 if (namedpart) {
973 namedpart->set_my_scope(p_scope);
974 }
975 }
976
977 void ParsedActualParameters::set_fullname(const string& p_fullname)
978 {
979 unnamedpart->set_fullname(p_fullname);
980 if (namedpart) {
981 namedpart->set_fullname(p_fullname);
982 }
983 }
984
985 void ParsedActualParameters::set_location(const char *p_filename, int p_lineno)
986 {
987 Location ::set_location(p_filename, p_lineno);
988 if (namedpart)
989 namedpart->set_location(p_filename, p_lineno);
990 unnamedpart->set_location(p_filename, p_lineno);
991 }
992
993 void ParsedActualParameters::set_location(const char *p_filename,
994 const YYLTYPE& p_yyloc)
995 {
996 Location ::set_location(p_filename, p_yyloc);
997 if (namedpart)
998 namedpart->set_location(p_filename, p_yyloc);
999 unnamedpart->set_location(p_filename, p_yyloc);
1000 }
1001
1002 void ParsedActualParameters::set_location(const char *p_filename,
1003 const YYLTYPE& p_firstloc,
1004 const YYLTYPE & p_lastloc)
1005 {
1006 Location ::set_location(p_filename, p_firstloc, p_lastloc);
1007 if (namedpart)
1008 namedpart->set_location(p_filename, p_firstloc, p_lastloc);
1009 unnamedpart->set_location(p_filename, p_firstloc, p_lastloc);
1010 }
1011
1012 void ParsedActualParameters::set_location(const char *p_filename, int p_first_line,
1013 int p_first_column, int p_last_line, int p_last_column)
1014 {
1015 Location ::set_location(p_filename, p_first_line, p_first_column,
1016 p_last_line, p_last_column);
1017 if (namedpart)
1018 namedpart->set_location(p_filename, p_first_line, p_first_column,
1019 p_last_line, p_last_column);
1020 unnamedpart->set_location(p_filename, p_first_line, p_first_column,
1021 p_last_line, p_last_column);
1022 }
1023
1024
1025 void ParsedActualParameters::dump(unsigned int level) const
1026 {
1027 DEBUG(level, "ParsedActualParameters at %p", (const void*)this);
1028 unnamedpart->dump(level+1);
1029 if (namedpart) {
1030 namedpart->dump(level+1);
1031 }
1032 }
1033 }
This page took 0.05609 seconds and 6 git commands to generate.