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