Sync with 5.4.2
[deliverable/titan.core.git] / compiler2 / ttcn3 / Templatestuff.cc
CommitLineData
970ed795 1///////////////////////////////////////////////////////////////////////////////
3abe9331 2// Copyright (c) 2000-2015 Ericsson Telecom AB
970ed795
EL
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
16namespace 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 // =================================
3f84031e 199
200 IndexedTemplate::IndexedTemplate(const IndexedTemplate& p)
201 {
202 index = p.index->clone();
203 temp = p.temp->clone();
204 }
970ed795
EL
205
206 IndexedTemplate::IndexedTemplate(FieldOrArrayRef *p_i, Template *p_t)
207 {
208 if (!p_i || !p_t) FATAL_ERROR("IndexedTemplate::IndexedTemplate()");
209 index = p_i;
210 temp = p_t;
211 }
212
213 IndexedTemplate::~IndexedTemplate()
214 {
215 delete index;
216 delete temp;
217 }
218
219 IndexedTemplate *IndexedTemplate::clone() const
220 {
3f84031e 221 return new IndexedTemplate(*this);
970ed795
EL
222 }
223
224 void IndexedTemplate::set_fullname(const string& p_fullname)
225 {
226 Node::set_fullname(p_fullname);
227 temp->set_fullname(p_fullname);
228 index->set_fullname(p_fullname);
229 }
230
231 void IndexedTemplate::set_my_scope(Scope *p_scope)
232 {
233 Node::set_my_scope(p_scope);
234 temp->set_my_scope(p_scope);
235 index->set_my_scope(p_scope);
236 }
237
238 void IndexedTemplate::set_code_section
239 (GovernedSimple::code_section_t p_code_section)
240 {
241 index->get_val()->set_code_section(p_code_section);
242 temp->set_code_section(p_code_section);
243 }
244
245 void IndexedTemplate::dump(unsigned level) const
246 {
247 index->dump(level);
248 temp->dump(level);
249 }
250
251 // =================================
252 // ===== IndexedTemplates
253 // =================================
3f84031e 254
255 IndexedTemplates::IndexedTemplates(const IndexedTemplates& p)
256 : Node(p)
257 {
258 for (size_t i = 0; i < p.its_v.size(); i++) {
259 its_v.add(p.its_v[i]->clone());
260 }
261 }
970ed795
EL
262
263 IndexedTemplates::~IndexedTemplates()
264 {
265 for (size_t i = 0; i < its_v.size(); i++) delete its_v[i];
266 its_v.clear();
267 }
268
269 IndexedTemplates *IndexedTemplates::clone() const
270 {
3f84031e 271 return new IndexedTemplates(*this);
970ed795
EL
272 }
273
274 void IndexedTemplates::set_fullname(const string& p_fullname)
275 {
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);
282 }
283 }
284
285 void IndexedTemplates::set_my_scope(Scope *p_scope)
286 {
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);
290 }
291
292 void IndexedTemplates::add_it(IndexedTemplate *p_it)
293 {
294 if (!p_it) FATAL_ERROR("NULL pointer: IndexedTemplates::add_it()");
295 its_v.add(p_it);
296 }
297
298 IndexedTemplate *IndexedTemplates::get_it_byIndex(size_t p_i)
299 {
300 return its_v[p_i];
301 }
302
303 // =================================
304 // ===== NamedTemplate
305 // =================================
306
307 NamedTemplate::NamedTemplate(Identifier *p_n, Template *p_t)
308 {
309 if (!p_n || !p_t) FATAL_ERROR("NamedTemplate::NamedTemplate()");
310 name = p_n;
311 temp = p_t;
312 }
3f84031e 313
314 NamedTemplate::NamedTemplate(const NamedTemplate& p)
315 {
316 name = p.name->clone();
317 temp = p.temp->clone();
318 }
970ed795
EL
319
320 NamedTemplate::~NamedTemplate()
321 {
322 delete name;
323 delete temp;
324 }
325
326 NamedTemplate *NamedTemplate::clone() const
327 {
3f84031e 328 return new NamedTemplate(*this);
970ed795
EL
329 }
330
331 void NamedTemplate::set_fullname(const string& p_fullname)
332 {
333 Node::set_fullname(p_fullname);
334 temp->set_fullname(p_fullname);
335 }
336
337 void NamedTemplate::set_my_scope(Scope *p_scope)
338 {
339 Node::set_my_scope(p_scope);
340 temp->set_my_scope(p_scope);
341 }
3abe9331 342
343 void NamedTemplate::set_name_to_lowercase()
344 {
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
351 // for that type)
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, "");
355 }
356 delete name;
357 name = new Identifier(Identifier::ID_NAME, new_name);
358 }
359 }
970ed795
EL
360
361 Template* NamedTemplate::extract_template()
362 {
363 Template * ret = temp;
364 temp = 0;
365 return ret;
366 }
367
368 void NamedTemplate::dump(unsigned level) const
369 {
370 name->dump(level);
371 temp->dump(level);
372 }
373
374 // =================================
375 // ===== NamedTemplates
376 // =================================
3f84031e 377
378 NamedTemplates::NamedTemplates(const NamedTemplates& p)
379 : Node(p), checked(p.checked)
380 {
381 for (size_t i = 0; i < p.nts_v.size(); i++) {
382 NamedTemplate* nt = p.nts_v[i]->clone();
383 nts_v.add(nt);
384 if (checked) {
385 nts_m.add(p.nts_m.get_nth_key(i), nt);
386 }
387 }
388 }
970ed795
EL
389
390 NamedTemplates::~NamedTemplates()
391 {
392 for (size_t i = 0; i < nts_v.size(); i++) delete nts_v[i];
393 nts_v.clear();
394 nts_m.clear();
395 }
396
397 NamedTemplates *NamedTemplates::clone() const
398 {
3f84031e 399 return new NamedTemplates(*this);
970ed795
EL
400 }
401
402 void NamedTemplates::set_fullname(const string& p_fullname)
403 {
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());
408 }
409 }
410
411 void NamedTemplates::set_my_scope(Scope *p_scope)
412 {
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);
415 }
416
417 void NamedTemplates::add_nt(NamedTemplate *p_nt)
418 {
419 if (!p_nt) FATAL_ERROR("NULL pointer:NamedTemplates::add_nt()");
420 nts_v.add(p_nt);
421 if (checked) {
422 const string& name = p_nt->get_name().get_name();
423 if (!nts_m.has_key(name)) nts_m.add(name, p_nt);
424 }
425 }
426
427 bool NamedTemplates::has_nt_withName(const Identifier& p_name)
428 {
429 if (!checked) chk_dupl_id(false);
430 return nts_m.has_key(p_name.get_name());
431 }
432
433 NamedTemplate *NamedTemplates::get_nt_byName(const Identifier& p_name)
434 {
435 if (!checked) chk_dupl_id(false);
436 return nts_m[p_name.get_name()];
437 }
438
439 void NamedTemplates::chk_dupl_id(bool report_errors)
440 {
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);
451 }
452 }
453 checked = true;
454 }
455
456 // =================================
457 // ===== LengthRestriction
458 // =================================
459
460 LengthRestriction::LengthRestriction(Value* p_val)
461 : Node(), checked(false), is_range(false)
462 {
463 if (!p_val)
464 FATAL_ERROR("LengthRestriction::LengthRestriction()");
465 single = p_val;
466 }
467
468 LengthRestriction::LengthRestriction(Value* p_lower, Value* p_upper)
469 : Node(), checked(false), is_range(true)
470 {
471 if (!p_lower)
472 FATAL_ERROR("LengthRestriction::LengthRestriction()");
473 range.lower = p_lower;
474 range.upper = p_upper;
475 }
476
477 LengthRestriction::~LengthRestriction()
478 {
479 if (is_range) {
480 delete range.lower;
481 delete range.upper;
482 } else delete single;
483 }
484
485 LengthRestriction *LengthRestriction::clone() const
486 {
487 FATAL_ERROR("LengthRestriction::clone");
488 }
489
490 void LengthRestriction::set_fullname(const string& p_fullname)
491 {
492 Node::set_fullname(p_fullname);
493 if (is_range) {
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);
497 }
498
499 void LengthRestriction::set_my_scope(Scope *p_scope)
500 {
501 if (is_range) {
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);
505 }
506
507 void LengthRestriction::chk(Type::expected_value_t expected_value)
508 {
509 if (checked) return;
510 checked = true;
511 Type *pool_int = Type::get_pooltype(Type::T_INT);
512 if (is_range) {
513 range.lower->set_my_governor(pool_int);
514 {
515 Error_Context cntxt(range.lower, "In lower boundary of the length "
516 "restriction");
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);
520 }
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);
531 }
532 } else {
533 v_int_lower_int = int_val_t((Int)0);
534 }
535 if (range.upper) {
536 range.upper->set_my_governor(pool_int);
537 {
538 Error_Context cntxt(range.lower, "In upper boundary of the length "
539 "restriction");
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);
543 }
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);
558 }
559 }
560 }
561 } else {
562 single->set_my_governor(pool_int);
563 {
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);
568 }
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);
576 }
577 }
578 }
579 }
580
581 void LengthRestriction::chk_array_size(ArrayDimension *p_dim)
582 {
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();
587 if (is_range) {
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());
595 error_flag = true;
596 } else {
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);
603 error_flag = true;
604 }
605 }
606 }
607 if (range.upper) {
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());
615 error_flag = true;
616 } else {
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);
623 error_flag = true;
624 }
625 }
626 }
627 }
628 } else {
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);
636 error_flag = true;
637 }
638 }
639 }
640 }
641 if (!error_flag)
642 warning("Length restriction is useless for an array template");
643 }
644
645 void LengthRestriction::chk_nof_elements(size_t nof_elements,
646 bool has_anyornone, const Location& p_loc, const char *p_what)
647 {
648 if (!checked) FATAL_ERROR("LengthRestriction::chk_nof_elements()");
649 if (is_range) {
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());
659 }
660 }
661 }
662 if (range.upper) {
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());
671 }
672 }
673 }
674 } else {
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) &&
685 !has_anyornone) {
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());
690 }
691 }
692 }
693 }
694
695 Value* LengthRestriction::get_single_value()
696 {
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();
700 }
701
702 Value *LengthRestriction::get_lower_value()
703 {
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();
707 }
708
709 Value *LengthRestriction::get_upper_value()
710 {
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;
714 }
715
716 void LengthRestriction::set_code_section
717 (GovernedSimple::code_section_t p_code_section)
718 {
719 if (is_range) {
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);
723 }
724
725 char *LengthRestriction::generate_code_init(char *str, const char *name)
726 {
727 expression_struct expr;
728 Code::init_expr(&expr);
729 char *init_stmt;
730 if (is_range) {
731 range.lower->generate_code_expr(&expr);
732 init_stmt = mprintf("%s.set_min_length(%s);\n", name, expr.expr);
733 if (range.upper) {
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,
737 expr.expr);
738 }
739 } else {
740 single->generate_code_expr(&expr);
741 init_stmt = mprintf("%s.set_single_length(%s);\n", name, expr.expr);
742 }
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);
751 Free(init_stmt);
752 return str;
753 }
754
755 char *LengthRestriction::rearrange_init_code(char *str)
756 {
757 if (is_range) {
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);
761 return str;
762 }
763
764 void LengthRestriction::append_stringRepr(string& str) const
765 {
766 str += "length(";
767 if (is_range) {
768 str += range.lower->get_stringRepr();
769 str += " .. ";
770 if (range.upper) str += range.upper->get_stringRepr();
771 else str += "infinity";
772 } else str += single->get_stringRepr();
773 str += ")";
774 }
775
776 void LengthRestriction::dump(unsigned level) const
777 {
778 DEBUG(level, "length restriction:");
779 if (is_range) {
780 range.lower->dump(level + 1);
781 DEBUG(level, "..");
782 if (range.upper) range.upper->dump(level + 1);
783 else DEBUG(level + 1, "infinity");
784 } else single->dump(level + 1);
785 }
786
787 // =================================
788 // ===== TemplateInstances
789 // =================================
790
791 TemplateInstances::TemplateInstances(const TemplateInstances& p)
792 : Node(p), Location(p), tis()
793 {
794 for (size_t i = 0; i < p.tis.size(); i++)
795 tis.add(p.tis[i]->clone());
796 }
797
798 TemplateInstances::~TemplateInstances()
799 {
800 for (size_t i = 0; i < tis.size(); i++) delete tis[i];
801 tis.clear();
802 }
803
804 TemplateInstances *TemplateInstances::clone() const
805 {
806 return new TemplateInstances(*this);
807 }
808
809 void TemplateInstances::set_fullname(const string& p_fullname)
810 {
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) + "]");
814 }
815
816 void TemplateInstances::set_my_scope(Scope *p_scope)
817 {
818 for (size_t i = 0; i < tis.size(); i++)
819 {
820 TemplateInstance*& tir = tis[i];
821 tir->set_my_scope(p_scope);
822 }
823 }
824
825 void TemplateInstances::add_ti(TemplateInstance *p_ti)
826 {
827 if (!p_ti) FATAL_ERROR("NULL pointer:TemplateInstances::add_ti()");
828 tis.add(p_ti);
829 }
830
831 void TemplateInstances::set_code_section
832 (GovernedSimple::code_section_t p_code_section)
833 {
834 for (size_t i=0; i<tis.size(); i++)
835 tis[i]->set_code_section(p_code_section);
836 }
837
838 void TemplateInstances::dump(unsigned level) const
839 {
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);
844 }
845 }
846 // =================================
847 // ===== NamedParam
848 // =================================
849
850 NamedParam::NamedParam(Identifier *id, TemplateInstance *t)
851 : Node(), Location(), name(id), tmpl(t)
852 {
853 }
854
855 NamedParam::NamedParam(const NamedParam& p)
856 : Node(p), Location(p), name(p.name->clone()), tmpl(p.tmpl->clone())
857 {
858 }
859
860 NamedParam::~NamedParam()
861 {
862 delete tmpl;
863 delete name;
864 }
865
866 NamedParam * NamedParam::clone() const {
867 return new NamedParam(*this);
868 }
869
870 void NamedParam::set_my_scope(Scope *p_scope)
871 {
872 tmpl->set_my_scope(p_scope);
873 }
874
875 void NamedParam::set_fullname(const string& p_fullname)
876 {
877 Node::set_fullname(p_fullname);
878 tmpl->set_fullname(p_fullname);
879 }
880
881 TemplateInstance * NamedParam::extract_ti()
882 {
883 TemplateInstance *retval = tmpl;
884 tmpl = 0;
885 return retval;
886 }
887
888 void NamedParam::dump(unsigned int level) const
889 {
890 name->dump(level+1);
891 tmpl->dump(level+1);
892 }
893 // =================================
894 // ===== NamedParams
895 // =================================
896
897 NamedParams::NamedParams()
898 : Node(), Location(), nps()
899 {
900 }
901
902 NamedParams * NamedParams::clone() const
903 {
904 FATAL_ERROR("NamedParams::clone");
905 }
906
907 NamedParams::~NamedParams()
908 {
909 for (size_t i = 0; i < nps.size(); i++) delete nps[i];
910 nps.clear();
911 }
912
913 void NamedParams::set_my_scope(Scope *p_scope)
914 {
915 for (size_t i = 0; i < nps.size(); i++) nps[i]->set_my_scope(p_scope);
916 }
917
918 void NamedParams::set_fullname(const string& p_fullname)
919 {
920 for (size_t i = 0; i < nps.size(); i++) nps[i]->set_fullname(p_fullname);
921 }
922
923 void NamedParams::add_np(NamedParam *p)
924 {
925 if (!p) FATAL_ERROR("NULL pointer: NamedParams::add_np()");
926 nps.add(p);
927 }
928
929 size_t NamedParams::get_nof_nps() const
930 {
931 return nps.size();
932 }
933
934 NamedParam *NamedParams::extract_np_byIndex(size_t p_i)
935 {
936 NamedParam * retval = nps[p_i];
937 nps[p_i] = 0;
938 return retval;
939 }
940
941 void NamedParams::dump(unsigned int level) const
942 {
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) {
946 if (nps[i] != 0) {
947 nps[i]->dump(level+1);
948 } else {
949 DEBUG(level+1, "NULL");
950 }
951 }
952 }
953 // =================================
954 // ===== ParsedActualParameters
955 // =================================
956
957 ParsedActualParameters::ParsedActualParameters(TemplateInstances *p_ti,
958 NamedParams *p_np)
959 : Node(), Location(), unnamedpart(p_ti ? p_ti : new TemplateInstances), namedpart(p_np)
960 {
961 }
962
963 ParsedActualParameters::ParsedActualParameters(const ParsedActualParameters& p)
964 : Node(p), Location(p), unnamedpart(p.unnamedpart->clone()),
965 namedpart (p.namedpart ? p.namedpart->clone() : 0)
966 {
967 }
968
969 ParsedActualParameters* ParsedActualParameters::clone() const
970 {
971 return new ParsedActualParameters(*this);
972 }
973
974 ParsedActualParameters::~ParsedActualParameters()
975 {
976 delete namedpart;
977 delete unnamedpart;
978 }
979
980 void ParsedActualParameters::add_np(NamedParam *np)
981 {
982 if (!namedpart) // we got away without one until now
983 {
984 namedpart = new NamedParams;
985 }
986 namedpart->add_np(np);
987 }
988
989 TemplateInstances* ParsedActualParameters::steal_tis()
990 {
991 TemplateInstances* temp = unnamedpart;
992 unnamedpart = new TemplateInstances;
993 return temp;
994 }
995
996 size_t ParsedActualParameters::get_nof_nps() const
997 {
998 return namedpart ? namedpart->get_nof_nps() : 0;
999 }
1000
1001 void ParsedActualParameters::set_my_scope(Common::Scope *p_scope)
1002 {
1003 unnamedpart->set_my_scope(p_scope);
1004 if (namedpart) {
1005 namedpart->set_my_scope(p_scope);
1006 }
1007 }
1008
1009 void ParsedActualParameters::set_fullname(const string& p_fullname)
1010 {
1011 unnamedpart->set_fullname(p_fullname);
1012 if (namedpart) {
1013 namedpart->set_fullname(p_fullname);
1014 }
1015 }
1016
1017 void ParsedActualParameters::set_location(const char *p_filename, int p_lineno)
1018 {
1019 Location ::set_location(p_filename, p_lineno);
1020 if (namedpart)
1021 namedpart->set_location(p_filename, p_lineno);
1022 unnamedpart->set_location(p_filename, p_lineno);
1023 }
1024
1025 void ParsedActualParameters::set_location(const char *p_filename,
1026 const YYLTYPE& p_yyloc)
1027 {
1028 Location ::set_location(p_filename, p_yyloc);
1029 if (namedpart)
1030 namedpart->set_location(p_filename, p_yyloc);
1031 unnamedpart->set_location(p_filename, p_yyloc);
1032 }
1033
1034 void ParsedActualParameters::set_location(const char *p_filename,
1035 const YYLTYPE& p_firstloc,
1036 const YYLTYPE & p_lastloc)
1037 {
1038 Location ::set_location(p_filename, p_firstloc, p_lastloc);
1039 if (namedpart)
1040 namedpart->set_location(p_filename, p_firstloc, p_lastloc);
1041 unnamedpart->set_location(p_filename, p_firstloc, p_lastloc);
1042 }
1043
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)
1046 {
1047 Location ::set_location(p_filename, p_first_line, p_first_column,
1048 p_last_line, p_last_column);
1049 if (namedpart)
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);
1054 }
1055
1056
1057 void ParsedActualParameters::dump(unsigned int level) const
1058 {
1059 DEBUG(level, "ParsedActualParameters at %p", (const void*)this);
1060 unnamedpart->dump(level+1);
1061 if (namedpart) {
1062 namedpart->dump(level+1);
1063 }
1064 }
1065}
This page took 0.062039 seconds and 5 git commands to generate.