Sync with 5.4.3
[deliverable/titan.core.git] / compiler2 / Type_chk.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 "Type.hh"
10 #include "Typestuff.hh" // FIXME CTs
11 #include "CompField.hh"
12 #include "CompType.hh"
13 #include "TypeCompat.hh"
14 #include "EnumItem.hh"
15 #include "SigParam.hh"
16
17 #include "Valuestuff.hh"
18 #include "main.hh"
19
20 #include "ttcn3/Ttcnstuff.hh"
21 #include "ttcn3/TtcnTemplate.hh"
22 #include "ttcn3/Templatestuff.hh"
23 #include "ttcn3/Attributes.hh"
24 #include "ttcn3/ArrayDimensions.hh"
25 #include "ttcn3/PatternString.hh"
26
27 #include "asn1/Tag.hh"
28 #include "XerAttributes.hh"
29
30 #include <ctype.h>
31 #include <stdlib.h> // for qsort
32 #include <string.h>
33
34 extern int rawAST_debug;
35
36 namespace Common {
37
38 using Ttcn::MultiWithAttrib;
39 using Ttcn::SingleWithAttrib;
40 using Ttcn::WithAttribPath;
41 using Ttcn::Qualifier;
42 using Ttcn::Qualifiers;
43
44 void Type::chk()
45 {
46 if(w_attrib_path) w_attrib_path->chk_global_attrib();
47 parse_attributes();
48 if(!tags_checked) {
49 tags_checked = true;
50 if(tags) tags->chk();
51 }
52 if (checked) return;
53 switch(typetype) {
54 case T_ERROR:
55 case T_NULL:
56 case T_BOOL:
57 case T_INT:
58 case T_REAL:
59 case T_BSTR:
60 case T_HSTR:
61 case T_OSTR:
62 case T_CSTR:
63 case T_USTR:
64 case T_UTF8STRING:
65 case T_NUMERICSTRING:
66 case T_PRINTABLESTRING:
67 case T_TELETEXSTRING:
68 case T_VIDEOTEXSTRING:
69 case T_IA5STRING:
70 case T_GRAPHICSTRING:
71 case T_VISIBLESTRING:
72 case T_GENERALSTRING:
73 case T_UNIVERSALSTRING:
74 case T_BMPSTRING:
75 case T_UTCTIME:
76 case T_GENERALIZEDTIME:
77 case T_OBJECTDESCRIPTOR:
78 case T_OID:
79 case T_ROID:
80 case T_ANY:
81 case T_EXTERNAL:
82 case T_EMBEDDED_PDV:
83 case T_UNRESTRICTEDSTRING:
84 case T_VERDICT:
85 case T_DEFAULT:
86 break;
87 case T_INT_A:
88 chk_Int_A();
89 break;
90 case T_ENUM_A:
91 chk_Enum_A();
92 break;
93 case T_ENUM_T:
94 chk_Enum_T();
95 break;
96 case T_BSTR_A:
97 chk_BStr_A();
98 break;
99 case T_OPENTYPE:
100 chk_SeCho_T();
101 break;
102 case T_ANYTYPE:
103 // TODO maybe check for address type and add it automagically, then fall through
104 case T_SEQ_T:
105 case T_SET_T:
106 case T_CHOICE_T:
107 chk_SeCho_T();
108 // If this sequence type has no attributes but one of its fields does,
109 // create an empty attribute structure.
110 if(!rawattrib && hasVariantAttrs() && hasNeedofRawAttrs())
111 rawattrib = new RawAST;
112 if(!textattrib && hasVariantAttrs() && hasNeedofTextAttrs())
113 textattrib = new TextAST;
114 if(!xerattrib && hasVariantAttrs() && hasNeedofXerAttrs())
115 xerattrib = new XerAttributes;
116 if (!jsonattrib && (hasVariantAttrs() || hasEncodeAttr(get_encoding_name(CT_JSON)) || hasNeedofJsonAttrs())) {
117 jsonattrib = new JsonAST;
118 }
119 break;
120 case T_CHOICE_A:
121 chk_Choice_A();
122 // TODO create an empty XerAttrib as above, when ASN.1 gets XER ?
123 // The code was originally for TTCN-only encodings.
124 break;
125 case T_SEQ_A:
126 case T_SET_A:
127 chk_Se_A();
128 // TODO create an empty XerAttrib as above, when ASN.1 gets XER ?
129 break;
130 case T_SEQOF:
131 case T_SETOF:
132 chk_SeOf();
133 break;
134 case T_REFD:
135 case T_ADDRESS:
136 chk_refd();
137 break;
138 case T_SELTYPE:
139 chk_seltype();
140 break;
141 case T_REFDSPEC:
142 case T_OCFT:
143 u.ref.type_refd->chk();
144 u.ref.component_internal = u.ref.type_refd->is_component_internal();
145 break;
146 case T_ARRAY:
147 chk_Array();
148 break;
149 case T_PORT:
150 u.port->chk();
151 if (w_attrib_path) u.port->chk_attributes(w_attrib_path);
152 break;
153 case T_SIGNATURE:
154 chk_Signature();
155 break;
156 case T_COMPONENT:
157 u.component->chk();
158 break;
159 case T_FUNCTION:
160 case T_ALTSTEP:
161 case T_TESTCASE:
162 chk_Fat();
163 break;
164 default:
165 FATAL_ERROR("Type::chk()");
166 } // switch
167
168 if(w_attrib_path) {
169 switch (get_type_refd_last()->typetype) {
170 case T_SEQ_T:
171 case T_SET_T:
172 case T_CHOICE_T:
173 // These types may have qualified attributes
174 break;
175 case T_SEQOF: case T_SETOF:
176 break;
177 default:
178 w_attrib_path->chk_no_qualif();
179 break;
180 }
181 }
182 checked = true;
183 if(tags) tags->set_plicit(this);
184
185 /*
186 Check all non-table subtype constraints. Table/relational constraints
187 are ignored here.
188 TODO: non-relational table constraints shall not be ignored.
189 */
190 if (check_subtype) check_subtype_constraints();
191
192 /*
193 * Checking the constraints can be done only if the entire type
194 * (including the nested typedefs) is checked, because the
195 * component relation constraint has to 'look' into other
196 * components.
197 */
198 if (!parent_type) chk_table_constraints();
199
200 if(rawattrib || is_root_basic()){
201 chk_raw();
202 }
203 if(textattrib || is_root_basic()) {
204 chk_text();
205 }
206
207 if (jsonattrib || is_root_basic()) {
208 chk_json();
209 }
210
211 // We need to call chk_xer() always because it is collecting
212 // XER attributes from parent types.
213 chk_xer();
214
215 chk_finished = true;
216 }
217
218 void Type::parse_attributes()
219 {
220 if (raw_parsed) return;
221
222 // The type has no attributes of its own; connect it to the nearest group
223 // or the module. This allows global attributes to propagate.
224 for (Type *t = this; t && w_attrib_path == 0; t = t->parent_type) {
225 switch (t->ownertype) {
226 case OT_TYPE_DEF: {
227 Ttcn::Def_Type *pwn = static_cast<Ttcn::Def_Type*>(t->owner);
228 Ttcn::Group *nearest_group = pwn->get_parent_group();
229
230 w_attrib_path = new WithAttribPath;
231 if (nearest_group) { // there is a group
232 w_attrib_path->set_parent(nearest_group->get_attrib_path());
233 }
234 else { // no group, use the module
235 Common::Module *mymod = t->my_scope->get_scope_mod();
236 // OT_TYPE_DEF is always from a TTCN-3 module
237 Ttcn::Module *my_ttcn_module = static_cast<Ttcn::Module *>(mymod);
238 w_attrib_path->set_parent(my_ttcn_module->get_attrib_path());
239 }
240 break; }
241
242 case OT_RECORD_OF:
243 case OT_COMP_FIELD:
244 continue; // try the enclosing type
245
246 default:
247 break;
248 }
249 break;
250 }
251
252 if ((hasVariantAttrs())
253 && (enable_text() || enable_raw() || enable_xer())) {
254 #ifndef NDEBUG
255 const char *fn = get_fullname().c_str();
256 if (rawAST_debug) {
257 fprintf(stderr, "parse_attributes for %s\n", fn);
258 }
259 #endif
260 bool new_raw=false; // a RawAST object was allocated here
261 bool new_text=false; // a TextAST object was allocated here
262 bool new_xer=false; // a XerAttribute object was allocated here
263 bool new_ber=false; // a BerAST object was allocated here
264 bool new_json = false; // a JsonAST object was allocated here
265 bool raw_found=false; // a raw attribute was found by the parser
266 bool text_found=false; // a text attribute was found by the parser
267 bool xer_found=false; // a XER attribute was found by the parser
268 bool ber_found=false; // a BER attribute was found by the parser
269 bool json_found = false; // a JSON attribute was found by the parser
270 raw_checked=false;
271 text_checked=false;
272 json_checked = false;
273 xer_checked=false;
274 bool override_ref=false;
275 // Parse RAW attributes
276 switch(typetype) {
277 case T_REFD: {
278 ReferenceChain refch(this, "While checking attributes");
279 if(w_attrib_path)
280 {
281 // Get all the attributes that apply (from outer scopes too).
282 // Outer (generic) first, inner (specific) last.
283 const vector<SingleWithAttrib> & real_attribs
284 = w_attrib_path->get_real_attrib();
285
286 // see if there's an encode with override
287 for(size_t i = real_attribs.size(); i > 0 && !override_ref; i--)
288 {
289 if(real_attribs[i-1]->has_override()
290 && real_attribs[i-1]->get_attribKeyword()
291 != SingleWithAttrib::AT_ENCODE)
292 override_ref = true;
293 }
294 }
295 if(!rawattrib && !override_ref){
296 Type *t=get_type_refd_last(&refch);
297 typetype_t basic_type=t->typetype;
298 t=this; // go back to the beginning
299 refch.reset();
300 while(!t->rawattrib && t->is_ref()) t=t->get_type_refd(&refch);
301 rawattrib=new RawAST(t->rawattrib,basic_type==T_INT);
302 if(!t->rawattrib && basic_type==T_REAL) rawattrib->fieldlength=64;
303 new_raw=true;
304 }
305 if(!textattrib && !override_ref){
306 Type *t=this;
307 refch.reset();
308 while(!t->textattrib && t->is_ref()) t=t->get_type_refd(&refch);
309 textattrib=new TextAST(t->textattrib);
310 new_text=true;
311 }
312 if (!jsonattrib && !override_ref){
313 Type *t = this;
314 refch.reset();
315 while (!t->jsonattrib && t->is_ref()) {
316 t = t->get_type_refd(&refch);
317 }
318 jsonattrib = new JsonAST(t->jsonattrib);
319 new_json = true;
320 }
321 }
322 // no break
323 case T_BOOL:
324 case T_INT:
325 case T_REAL:
326 case T_BSTR:
327 case T_HSTR:
328 case T_OSTR:
329 case T_CSTR: // TTCN-3 charstring
330 case T_ENUM_T:
331 /* The list of types supporting RAW encoding is described in the
332 * API guide, section 3.3; this batch of labels plus the next three
333 * accurately match the list.
334 *
335 * For TEXT, it's section 3.4; the list does not include real and
336 * bin/hex/octet strings
337 */
338 case T_USTR: // TTCN-3 universal charstring, this is an addition for XER attributes
339 case T_VERDICT: // TTCN-3 verdict, for XER
340
341 if(rawattrib==NULL){
342 rawattrib= new RawAST(typetype==T_INT);
343 if(typetype==T_REAL) rawattrib->fieldlength=64;
344 new_raw=true;
345 }
346 if(textattrib==NULL){textattrib= new TextAST; new_text=true;}
347 if (xerattrib==NULL) {
348 xerattrib = new XerAttributes; new_xer = true;
349 }
350 if (berattrib==NULL) {
351 berattrib = new BerAST;
352 new_ber = true;
353 }
354
355 if (NULL == jsonattrib) {
356 jsonattrib = new JsonAST;
357 new_json = true;
358 }
359
360 if(w_attrib_path)
361 {
362 vector<SingleWithAttrib> const &real_attribs
363 = w_attrib_path->get_real_attrib();
364 // These are attributes without qualifiers.
365
366 size_t nof_elements = real_attribs.size();
367 for(size_t i = 0; i < nof_elements; i++)
368 {
369 SingleWithAttrib *temp_single = real_attribs[i];
370 if (temp_single->get_attribKeyword() ==
371 SingleWithAttrib::AT_VARIANT) { // only "variant" is parsed
372 parse_rawAST(rawattrib, textattrib, xerattrib, berattrib, jsonattrib,
373 temp_single->get_attribSpec(), get_length_multiplier(),
374 my_scope->get_scope_mod(),
375 raw_found, text_found, xer_found, ber_found, json_found);
376 // textattrib->print_TextAST();
377 // rawattrib->print_RawAST();
378 // xerattrib->print(get_fullname().c_str());
379 } // if AT_VARIANT
380 } // next i
381 }
382
383 if(!raw_found && new_raw){ delete rawattrib; rawattrib=NULL;}
384 if(!text_found && new_text){ delete textattrib; textattrib=NULL;}
385 if(!xer_found && new_xer){ delete xerattrib; xerattrib = NULL; }
386 if(!ber_found && new_ber){ delete berattrib; berattrib = NULL; }
387 if (!json_found && new_json) {
388 delete jsonattrib;
389 jsonattrib = NULL;
390 }
391 break;
392 case T_SEQOF:
393 case T_SETOF:
394 case T_CHOICE_T:
395 case T_SEQ_T:
396 case T_SET_T:
397 case T_ANYTYPE:
398 case T_ARRAY:
399 if(rawattrib==NULL) {rawattrib= new RawAST; new_raw=true;}
400 if(textattrib==NULL){textattrib= new TextAST; new_text=true;}
401 if(xerattrib==NULL) {xerattrib = new XerAttributes; new_xer = true;}
402 if(berattrib==NULL) {berattrib = new BerAST; new_ber = true;}
403 if (NULL == jsonattrib) {
404 jsonattrib = new JsonAST;
405 new_json = true;
406 }
407
408 if(w_attrib_path)
409 {
410 vector<SingleWithAttrib> const &real_attribs
411 = w_attrib_path->get_real_attrib();
412
413 //calculate the type's attributes (the qualifierless ones)
414 size_t nof_elements = real_attribs.size();
415 for(size_t i = 0; i < nof_elements; i++)
416 {
417 SingleWithAttrib *temp_single = real_attribs[i];
418 if(temp_single->get_attribKeyword() == SingleWithAttrib::AT_VARIANT
419 && (!temp_single->get_attribQualifiers()
420 || temp_single->get_attribQualifiers()->get_nof_qualifiers()
421 == 0)){
422 // raw/text/xer/ber/json attributes for the whole record/seq.
423 // (own or inherited)
424 parse_rawAST(rawattrib, textattrib, xerattrib, berattrib, jsonattrib,
425 temp_single->get_attribSpec(), get_length_multiplier(),
426 my_scope->get_scope_mod(),
427 raw_found, text_found, xer_found, ber_found, json_found);
428 }
429 }
430 //calculate the components attributes
431 MultiWithAttrib* self_attribs = w_attrib_path->get_with_attr();
432 if(self_attribs)
433 {
434 MultiWithAttrib* new_self_attribs = new MultiWithAttrib;
435 SingleWithAttrib* swa = 0;
436
437 // copy all the "encode" attributes
438 for(size_t i = 0; i < self_attribs->get_nof_elements(); i++)
439 {
440 if(self_attribs->get_element(i)->get_attribKeyword()
441 == SingleWithAttrib::AT_ENCODE)
442 {
443 // Copy the attribute without qualifiers
444 const SingleWithAttrib* swaref = self_attribs->get_element(i);
445 swa = new SingleWithAttrib(swaref->get_attribKeyword(),
446 swaref->has_override(), 0, swaref->get_attribSpec().clone());
447 new_self_attribs->add_element(swa);
448 }
449 }
450
451 if(new_self_attribs->get_nof_elements() > 0)
452 { // One or more "encode"s were copied; create a context for them.
453 // This is a member because is has to be owned by this Type
454 // (the components only refer to it).
455 encode_attrib_path = new WithAttribPath;
456 encode_attrib_path->set_with_attr(new_self_attribs);
457 encode_attrib_path->set_parent(w_attrib_path->get_parent());
458 }
459 else delete new_self_attribs;
460
461 // This should be bool, but gcc 4.1.2-sol8 generates incorrect code
462 // with -O2 :(
463 const int se_of = (typetype == T_SEQOF || typetype == T_SETOF ||
464 typetype == T_ARRAY);
465 const size_t nof_comps = se_of ? 1 : get_nof_comps();
466
467 // Distribute the attributes with qualifiers to the components.
468 // If the type is a sequence-of or set-of, we pretend it to have
469 // one component with the name "_0" (a valid TTCN-3 identifier
470 // can't begin with an underscore). compiler.y has created
471 // the appropriate identifier in the qualifier for a "[-]".
472 for(size_t i = 0; i < nof_comps; i++)
473 {
474 const Identifier& comp_id =
475 se_of ? underscore_zero : get_comp_id_byIndex(i);
476 MultiWithAttrib* component_attribs = new MultiWithAttrib;
477
478 for(size_t j = 0; j < self_attribs->get_nof_elements(); j++)
479 {
480 const SingleWithAttrib *temp_single =
481 self_attribs->get_element(j);
482 Qualifiers* temp_qualifiers =
483 temp_single->get_attribQualifiers();
484 if( !temp_qualifiers
485 || temp_qualifiers->get_nof_qualifiers() == 0) continue;
486
487 Qualifiers* calculated_qualifiers = new Qualifiers;
488 bool qualifier_added = false;
489 for(size_t k=0; k < temp_qualifiers->get_nof_qualifiers(); )
490 {
491 const Qualifier* temp_qualifier =
492 temp_qualifiers->get_qualifier(k);
493 if(temp_qualifier->get_nof_identifiers() > 0
494 && (*temp_qualifier->get_identifier(0) == comp_id))
495 {
496 // Found a qualifier whose first identifier matches
497 // the component name. Remove the qualifier from the
498 // enclosing type, chop off its head,
499 // and add it to the component's qualifiers.
500 calculated_qualifiers->add_qualifier(
501 temp_qualifier->get_qualifier_without_first_id());
502 temp_qualifiers->delete_qualifier(k);
503 qualifier_added = true;
504 }
505 else k++;
506 } // next qualifier
507
508 if(qualifier_added)
509 {
510 // A copy of temp_single, with new qualifiers
511 SingleWithAttrib* temp_single2
512 = new SingleWithAttrib(temp_single->get_attribKeyword(),
513 temp_single->has_override(),
514 calculated_qualifiers,
515 temp_single->get_attribSpec().clone());
516 temp_single2->set_location(*temp_single);
517 component_attribs->add_element(temp_single2);
518 }
519 else delete calculated_qualifiers;
520 } // next attrib
521
522 if (component_attribs->get_nof_elements() > 0) {
523 Type* component_type = se_of ?
524 get_ofType() : get_comp_byIndex(i)->get_type();
525
526 if(encode_attrib_path)
527 // The record's "encode" attributes (only) apply to the fields.
528 // Interpose them in the path of the field.
529 component_type->set_parent_path(encode_attrib_path);
530 else
531 component_type->set_parent_path(w_attrib_path->get_parent());
532
533 component_type->set_with_attr(component_attribs);
534 }
535 else delete component_attribs;
536 } // next component index
537
538 // Any remaining attributes with qualifiers are erroneous
539 for(size_t i = 0; i < self_attribs->get_nof_elements();)
540 {
541 Qualifiers *temp_qualifiers = self_attribs->get_element(i)
542 ->get_attribQualifiers();
543 if(temp_qualifiers && temp_qualifiers->get_nof_qualifiers() != 0)
544 {
545 size_t nof_qualifiers = temp_qualifiers->get_nof_qualifiers();
546 for(size_t j = 0; j < nof_qualifiers; j++)
547 {
548 const Qualifier *temp_qualifier =
549 temp_qualifiers->get_qualifier(j);
550 const Identifier& tmp_id = *temp_qualifier->get_identifier(0);
551 // Special case when trying to reference the inner type
552 // of a record-of when it wasn't a record-of.
553 if (tmp_id == underscore_zero) temp_qualifier->error(
554 "Invalid field qualifier [-]");
555 else temp_qualifier->error("Invalid field qualifier %s",
556 tmp_id.get_dispname().c_str());
557 }
558 self_attribs->delete_element(i);
559 }else{
560 i++;
561 }
562 } // next i
563 } // end if(self_attribs)
564 } // end if(w_attrib_path)
565 if (!raw_found && new_raw) { delete rawattrib; rawattrib = NULL; }
566 if (!text_found && new_text){ delete textattrib; textattrib= NULL; }
567 if (!xer_found && new_xer) { delete xerattrib; xerattrib = NULL; }
568 if (!ber_found && new_ber) { delete berattrib; berattrib = NULL; }
569 if (!json_found && new_json) {
570 delete jsonattrib;
571 jsonattrib = NULL;
572 }
573 break;
574 default:
575 // nothing to do, ASN1 types or types without defined raw attribute
576 break;
577 } // switch
578 if (rawattrib && !enable_raw()) { delete rawattrib; rawattrib = NULL;}
579 if (textattrib&& !enable_text()){ delete textattrib; textattrib= NULL;}
580 if (xerattrib && !enable_xer()) { delete xerattrib; xerattrib = NULL;}
581 if (berattrib && !enable_ber()) { delete berattrib; berattrib = NULL;}
582 if (NULL != jsonattrib && !enable_json()) {
583 delete jsonattrib;
584 jsonattrib = NULL;
585 }
586 } // endif( hasVariantAttrs && enable_{raw,text,xer} )
587
588 raw_parsed = true;
589 }
590
591 // Implements "NAME AS ..." transformations.
592 void change_name(string &name, XerAttributes::NameChange change) {
593 switch (change.kw_) {
594 case NamespaceSpecification::NO_MANGLING:
595 break; // cool, nothing to do!
596
597 case NamespaceSpecification::UPPERCASED:
598 // Walking backwards calls size() only once. Loop var must be signed.
599 for (int i = name.size()-1; i >= 0; --i) {
600 name[i] = toupper(name[i]);
601 }
602 break;
603
604 case NamespaceSpecification::LOWERCASED:
605 for (int i = name.size()-1; i >= 0; --i) {
606 name[i] = tolower(name[i]);
607 }
608 break;
609
610 case NamespaceSpecification::CAPITALIZED:
611 name[0] = toupper(name[0]);
612 break;
613
614 case NamespaceSpecification::UNCAPITALIZED:
615 name[0] = tolower(name[0]);
616 break;
617
618 default: // explicitly specified name
619 name = change.nn_;
620 break;
621 } // switch for NAME
622 }
623
624 void Type::chk_xer_any_attributes()
625 {
626 Type * const last = get_type_refd_last();
627 switch (last->typetype == T_SEQOF ?
628 last->u.seof.ofType->get_type_refd_last()->typetype : 0) {
629 case T_UTF8STRING: // SEQUENCE OF UTF8String, ASN.1
630 case T_USTR: // record of universal charstring
631 break;
632 // fall through
633 default:
634 error("ANY-ATTRIBUTES can only be applied to record of string");
635 break;
636 } // switch
637
638 switch (parent_type != NULL ? parent_type->typetype : 0) {
639 case T_SEQ_A: case T_SET_A:
640 case T_SEQ_T: case T_SET_T:
641 for (size_t x = 0; x < parent_type->get_nof_comps(); ++x) {
642 CompField * cf = parent_type->get_comp_byIndex(x);
643 if (cf->get_type() != this) continue;
644 if (cf->has_default()) {
645 error("The field with ANY-ATTRIBUTES cannot have DEFAULT");
646 }
647 }
648 break;
649 default:
650 error("ANY-ATTRIBUTES can only be applied to a member of "
651 "SEQUENCE, SET, record or set");
652 break;
653 }
654
655 if (xerattrib->untagged_
656 || (parent_type && parent_type->xerattrib && parent_type->xerattrib->untagged_)) {
657 error("Neither the type with ANY-ATTRIBUTES, nor its enclosing type "
658 "may be marked UNTAGGED");
659 }
660 }
661
662 void Type::chk_xer_any_element()
663 {
664 Type *const last = get_type_refd_last();
665 switch (last->typetype) {
666 case T_UTF8STRING: // UTF8String, ASN.1
667 case T_USTR: // universal charstring
668 break; // acceptable
669 case T_SEQOF: {
670 /* A special case for TTCN-3 where applying ANY-ELEMENT to the record-of
671 * has the same effect as applying it to the string member.
672 * This should no longer be necessary now that we can refer
673 * to the embedded type of a record-of with [-], but it has to stay
674 * unless the standard deprecates it. */
675 Type *oftype = last->u.seof.ofType;
676 if (oftype->xerattrib == 0) oftype->xerattrib = new XerAttributes;
677 // Transfer the ANY-ATTRIBUTE from the record-of to its member type
678 oftype->xerattrib->anyElement_ = xerattrib->anyElement_;
679 xerattrib->anyElement_.nElements_ = 0;
680 xerattrib->anyElement_.uris_ = 0;
681 // Re-check the member type since we fiddled with it
682 const char * type_name = "record of";
683 Error_Context cntxt(this, "In embedded type of %s", type_name);
684 oftype->xer_checked = false;
685 oftype->chk_xer();
686 break; }
687 default:
688 error("ANY-ELEMENT can only be applied to UTF8String "
689 "or universal charstring type");
690 break;
691 } // switch
692
693 if (xerattrib->attribute_ || xerattrib->base64_ || xerattrib->untagged_
694 || xerattrib->defaultForEmpty_ != NULL
695 || xerattrib->whitespace_ != XerAttributes::PRESERVE) {
696 error("A type with ANY-ELEMENT may not have any of the following encoding instructions: "
697 "ATTRIBUTE, BASE64, DEFAULT-FOR-EMPTY, PI-OR-COMMENT, UNTAGGED or WHITESPACE");
698 }
699 }
700
701 void Type::chk_xer_attribute()
702 {
703 if (xerattrib->element_) {
704 error("ELEMENT and ATTRIBUTE are incompatible");
705 }
706
707 switch (parent_type!=NULL ? parent_type->typetype :-0) {
708 case 0: // no parent accepted in case a field of this type is declared
709 case T_SEQ_A: case T_SEQ_T:
710 case T_SET_A: case T_SET_T:
711 break; // acceptable
712 default:
713 error("A type with ATTRIBUTE must be a member of "
714 "SEQUENCE, SET, record or set");
715 break;
716 }
717
718 if (xerattrib->untagged_
719 || (parent_type && parent_type->xerattrib && parent_type->xerattrib->untagged_)) {
720 error("Neither the type with ATTRIBUTE, nor its enclosing type "
721 "may be marked UNTAGGED");
722 }
723
724 if (has_ae(xerattrib)) {
725 // TODO: || (xerattrib->defaultForEmpty_ && it is an ASN.1 type)
726 // DEFAULT-FOR-EMPTY is allowed only for TTCN-3
727 error("A type with ATTRIBUTE shall not also have any of the final "
728 "encoding instructions ANY-ELEMENT" /*", DEFAULT-FOR-EMPTY"*/ " or PI-OR-COMMENT");
729 }
730 }
731
732 /// CompField cache
733 struct CFCache {
734 /// Pointer to the field
735 CompField *cf;
736 /// The type of the field
737 Type *top;
738 /// The ultimate type, top->get_type_refd_last()
739 Type *last;
740 /// The typetype of last, on which we sort. Its name is meant to be
741 /// mnemonic (it belongs to \c last, not \c top)
742 Type::typetype_t lastt;
743 };
744
745 /// Comparison function for CFCache based on typetype
746 int tcomp(const void *l, const void *r)
747 {
748 int retval = ((const CFCache*)l)->lastt - ((const CFCache*)r)->lastt;
749 return retval;
750 }
751
752 /** Find the original component name if it was changed by TEXT
753 *
754 * If there is a TEXT whose \a new_text matches \p text, return
755 * the corresponding \a target.
756 *
757 * If there are no TEXT coding instructions, always returns \p text.
758 *
759 * @param[in,out] text on input, a name possibly modified by any TEXT encoding
760 * instruction; on output, the actual component name
761 */
762 void Type::target_of_text(string & text)
763 {
764 for (size_t t = 0; t < xerattrib->num_text_; ++t) {
765 NamespaceSpecification& txt = xerattrib->text_[t];
766
767 if ((unsigned long)txt.prefix == 0
768 ||(unsigned long)txt.prefix == NamespaceSpecification::ALL) {
769 FATAL_ERROR("Type::target_of_text()");
770 continue;
771 }
772
773 string target(txt.target);
774
775 switch ((unsigned long)txt.new_text) {
776 case NamespaceSpecification::CAPITALIZED: // tARGET -> TARGET
777 target[0] = toupper(target[0]);
778 break;
779 case NamespaceSpecification::UNCAPITALIZED:
780 target[0] = tolower(target[0]); // TARGET -> tARGET
781 break;
782 case NamespaceSpecification::UPPERCASED:
783 for (int si = target.size() - 1; si >= 0; --si) {
784 target[si] = toupper(target[si]);
785 }
786 break;
787 case NamespaceSpecification::LOWERCASED:
788 for (int si = target.size() - 1; si >= 0; --si) {
789 target[si] = tolower(target[si]);
790 }
791 break;
792
793 case 0: // "text" not possible
794 FATAL_ERROR("Type::target_of_text() Text with no target and DFE");
795 break;
796
797 default: // it's a string, "text 'field' as 'string'"
798 target = txt.uri;
799 break;
800 } // switch new_text
801
802 if (target == text) {
803 text = txt.target; // we want the value before the change
804 break;
805 }
806 } // next text
807 }
808
809 // The suffix of the name of the variable which contains the D-F-E value.
810 static const string dfe_suffix("_dfe");
811
812 /** Construct a Value to represent defaultForEmpty
813 *
814 * @param last pointer to a Type which is the end of the reference chain,
815 * usually this->get_type_refd_last()
816 * @param dfe_str string containing the value from defaultForEmpty
817 * @return a newly allocated Common::Value
818 */
819 Value *Type::new_value_for_dfe(Type *last, const char *dfe_str)
820 {
821 string defaultstring(dfe_str);
822 switch (last->typetype) {
823 case T_CSTR:
824 case T_USTR:
825 case T_UTF8STRING:
826 return new Value(Common::Value::V_CSTR,
827 new string(defaultstring));
828
829 case T_INT:
830 case T_INT_A:
831 return new Value(Common::Value::V_INT,
832 new int_val_t(dfe_str, *this));
833
834 case T_REAL: {
835 const Real& rval = string2Real(dfe_str, *this);
836 return new Value(Value::V_REAL, rval);
837 }
838
839 case T_BOOL: {
840 if (!strcmp(dfe_str, "true")
841 ||!strcmp(dfe_str, "1")) {
842 return new Value(Value::V_BOOL, true);
843 }
844 else if (!strcmp(dfe_str, "false")
845 || !strcmp(dfe_str, "0")) {
846 return new Value(Value::V_BOOL, false);
847 }
848 else error("Invalid boolean default value");
849 break;
850 }
851
852 case T_ENUM_A: case T_ENUM_T: {
853 // If there is a TEXT, the DFE value corresponds to TextToBeUsed.
854 // Fetch the "real" name of the field (Target).
855
856 target_of_text(defaultstring);
857
858 Identifier *val_id = new Identifier(Common::Identifier::ID_TTCN, // FIXME when ASN1 is supported
859 defaultstring);
860
861 if (!last->has_ei_withName(*val_id)) {
862 error("No enumeration item item '%s'", defaultstring.c_str());
863 #ifndef NDEBUG
864 for (size_t ee=0; ee < last->u.enums.eis->get_nof_eis(); ++ee) {
865 note("Maybe %s", last->u.enums.eis->get_ei_byIndex(ee)->get_name().get_name().c_str());
866 }
867 #endif
868 }
869
870 return new Value(Common::Value::V_ENUM, val_id);
871 }
872
873 case T_CHOICE_A: case T_CHOICE_T: {
874 // Try to guess which alternative the given DFE text belongs to.
875 // Sort the fields based on typetype, so BOOL, INT, REAL, ENUM
876 // are tried before the various string types
877 // (any string looks 'right' for a string value).
878 size_t num_comps = last->get_nof_comps();
879 CFCache *sorted = new CFCache[num_comps];
880 for (size_t c = 0; c < num_comps; c++) {
881 CompField *cf = last->get_comp_byIndex(c);
882 Type *cft = cf->get_type();
883 Type *cftlast = cft->get_type_refd_last();
884 sorted[c].cf = cf;
885 sorted[c].top = cft;
886 sorted[c].last = cftlast;
887 sorted[c].lastt = cftlast->typetype;
888 }
889 qsort(sorted, num_comps, sizeof(CFCache), tcomp);
890
891 Value * retval = 0;
892 size_t c;
893 for (c = 0; c < num_comps && retval == 0; c++) {
894 CFCache &current = sorted[c];
895 // We can't just call new_value_for_dfe(), because some alternatives
896 // would generate errors even if a later type could accept the value.
897 switch (current.lastt) {
898 case T_BOOL:
899 if (!strcmp(dfe_str, "true")
900 ||!strcmp(dfe_str, "1")) {
901 retval = new Value(Value::V_BOOL, true);
902 }
903 else if (!strcmp(dfe_str, "false")
904 || !strcmp(dfe_str, "0")) {
905 retval = new Value(Value::V_BOOL, false);
906 }
907 break;
908
909 case T_INT: case T_INT_A: {
910 const char *start = dfe_str, *end;
911 while (isspace((const unsigned char)*start)) ++start;
912 if (*start == '+') ++start;
913 int ndigits = BN_dec2bn(NULL, start); // includes any '-' sign
914 end = start + ndigits;
915 // Pretend that all trailing whitespace characters were digits
916 while (isspace(*end)) ++ndigits, ++end;
917
918 // Check that all the string was used up in the conversion,
919 // otherwise "3.1415" and "1e6" would appear as integers.
920 if (defaultstring.size() == (size_t)ndigits + (start - dfe_str )) {
921 retval = current.top->new_value_for_dfe(current.last, start);
922 }
923 break; }
924
925 case T_REAL: {
926 float f;
927 char tail[2];
928 int num_converted = sscanf(dfe_str, "%f %1s", &f, tail);
929 // If tail was converted (num_converted>1) that's an error
930 if (num_converted == 1) { // sscanf was happy
931 retval = current.top->new_value_for_dfe(current.last, dfe_str);
932 }
933 break; }
934
935 case T_ENUM_A: case T_ENUM_T: {
936 current.top->target_of_text(defaultstring);
937 Identifier alt(Identifier::ID_TTCN, defaultstring);
938 if (current.last->has_ei_withName(alt)) {
939 retval = current.top->new_value_for_dfe(current.last, dfe_str);
940 }
941 break; }
942
943 case T_CSTR:
944 case T_USTR:
945 case T_UTF8STRING: {
946 retval = current.top->new_value_for_dfe(current.last, dfe_str);
947 break; }
948
949 default:
950 break;
951 } // switch
952 } // next c
953
954 if (retval != 0) {
955 c--;
956 retval->set_genname(sorted[c].top->genname, dfe_suffix);
957 retval->set_my_scope(sorted[c].top->my_scope);
958 retval->set_my_governor(sorted[c].top);
959 Value *choice_retval = new Value(Value::V_CHOICE,
960 new Identifier(sorted[c].cf->get_name()), retval);
961 retval = choice_retval;
962 }
963
964 delete [] sorted;
965 return retval; }
966
967 /* Useless without a properly constructed Value(V_SEQ)
968 case T_SEQ_A: case T_SEQ_T: {
969 NamedValues *nvs = new NamedValues;
970 //NamedValue *nv = new NamedValue(new Identifier, new Value);
971 nvs->add_nv(nv);
972 xerattrib->defaultValue_ = new Value(Value::V_SEQ, nvs);
973 break; }
974 */
975
976 default: // complain later
977 break;
978 } // switch
979 return 0;
980 }
981
982 void Type::chk_xer_dfe()
983 {
984 Type * const last = get_type_refd_last();
985
986 if (/* TODO xerattrib->attribute_ is error for ASN.1 only */
987 xerattrib->untagged_ || has_ae(xerattrib)) {
988 error("A type with DEFAULT-FOR-EMPTY shall not have any of the final "
989 "encoding instructions ANY-ELEMENT, ATTRIBUTE, UNTAGGED."); // 23.2.8
990 }
991
992 if (is_charenc() == Yes) {
993 xerattrib->defaultValue_ = new_value_for_dfe(last, xerattrib->defaultForEmpty_);
994
995 if (xerattrib->defaultValue_ != 0) {
996 xerattrib->defaultValue_->set_genname(this->genname, dfe_suffix);
997 xerattrib->defaultValue_->set_my_scope(this->my_scope);
998 xerattrib->defaultValue_->set_my_governor(last);
999 }
1000 else {
1001 error("DEFAULT-FOR-EMPTY not supported for character-encodable type %s",
1002 last->get_stringRepr().c_str());
1003 }
1004 }
1005 else if (last->typetype == T_SEQ_A || last->typetype == T_SEQ_T) {
1006 // If DEFAULT-FOR-EMPTY applies to a record (SEQUENCE), then only one
1007 // component can produce element content, and it should be the last,
1008 // because all the others should have ATTRIBUTE or ANY-ATTRIBUTE,
1009 // and those are moved to the front. 23.2.2 b)
1010 // FIXME only b) appears to have this restriction, not c)d)e)
1011 const size_t num_cf = last->get_nof_comps();
1012 if (num_cf > 0) {
1013 CompField *cf = last->get_comp_byIndex(num_cf-1); // last field
1014 Type *cft = cf->get_type(); // cft: CompField type
1015 cft = cft->get_type_refd_last();
1016 //typetype_t cftt = cft->get_typetype();
1017
1018 xerattrib->defaultValue_ = new_value_for_dfe(cft, xerattrib->defaultForEmpty_);
1019 if (xerattrib->defaultValue_ != 0) {
1020 xerattrib->defaultValue_->set_genname(last->genname, string("_dfe"));
1021 xerattrib->defaultValue_->set_my_scope(cft->my_scope);
1022 xerattrib->defaultValue_->set_my_governor(cft);
1023 }
1024 else {
1025 error("DEFAULT-FOR-EMPTY not supported for fields of type %s",
1026 cft->get_stringRepr().c_str());
1027 }
1028 } // endif comps >0
1029 } // if SEQ/SET
1030 else {
1031 error("DEFAULT-FOR-EMPTY not applicable to type");
1032 }
1033 }
1034
1035 void Type::chk_xer_embed_values(int num_attributes)
1036 {
1037 Type * const last = get_type_refd_last();
1038
1039 enum complaint_type { ALL_GOOD, HAVE_DEFAULT, UNTAGGED_EMBEDVAL,
1040 NOT_SEQUENCE, EMPTY_SEQUENCE, FIRST_NOT_SEQOF, SEQOF_NOT_STRING,
1041 SEQOF_BAD_LENGTH, UNTAGGED_OTHER } ;
1042 complaint_type complaint = ALL_GOOD;
1043 size_t expected_length = (size_t)-1;
1044 Type *cf0t = 0; // type of first component
1045 CompField *cf = 0;
1046 switch (last->typetype) {
1047 case T_SEQ_A: case T_SEQ_T: { // 25.2.1, the type must be a sequence
1048 const size_t num_cf = last->get_nof_comps();
1049 if (num_cf == 0) {
1050 complaint = EMPTY_SEQUENCE; // must have a "first component"
1051 break;
1052 }
1053 CompField *cf0 = last->get_comp_byIndex(0);
1054 cf0t = cf0->get_type()->get_type_refd_last();
1055 if (cf0->has_default()) {
1056 complaint = HAVE_DEFAULT;
1057 break; // 25.2.1 first component cannot have default
1058 }
1059
1060 switch (cf0t->get_typetype()) { // check the first component
1061 case T_SEQOF: {
1062 Type *cfot = cf0t->get_ofType(); // embedded type
1063 switch (cfot->get_type_refd_last()->get_typetype()) {
1064 case T_UTF8STRING:
1065 case T_USTR: { // hooray, a SEQUENCE OF some string
1066 if ( (cf0t->xerattrib && cf0t->xerattrib->untagged_)
1067 || (cfot->xerattrib && cfot->xerattrib->untagged_)) {
1068 complaint = UNTAGGED_EMBEDVAL; // 25.2.2
1069 break;
1070 }
1071
1072 // Check length restriction on the record of. If there is one,
1073 // it better be the correct number.
1074 // FIXME: if there is also a USE-NIL, it cannot have a length restriction; only check at runtime
1075 const SubType *sub = cf0t->sub_type;
1076 const Int len = sub ? sub->get_length_restriction() :-1;
1077 // get_length_restriction() itself may return -1
1078 expected_length = num_cf -num_attributes -xerattrib->useOrder_;
1079 if (len > 0 && (size_t)len != expected_length) {
1080 // The +1 from 25.2.6 b) is compensated because
1081 // the EMBED-VALUES member itself is ignored.
1082 complaint = SEQOF_BAD_LENGTH;
1083 break;
1084 }
1085 break; } //acceptable
1086
1087 default: // 25.2.1
1088 complaint = SEQOF_NOT_STRING;
1089 break;
1090 } // switch
1091 break; }
1092
1093 default: // 25.2.1
1094 complaint = FIRST_NOT_SEQOF;
1095 break;
1096 } // switch(type of first component)
1097
1098 for (size_t c = 1; c < num_cf; ++c) { // check the other components
1099 cf = last->get_comp_byIndex(c);
1100 Type *cft = cf->get_type()->get_type_refd_last();
1101 if (cft->xerattrib && cft->xerattrib->untagged_ && (cft->is_charenc() == Yes)){
1102 complaint = UNTAGGED_OTHER;
1103 break;
1104 }
1105 }
1106 break; } // case T_SEQ*
1107
1108 default:
1109 complaint = NOT_SEQUENCE;
1110 break;
1111 } // switch typetype
1112
1113 // TODO 25.2.4, 25.2.5
1114 if (complaint == ALL_GOOD) embed_values_possible = true;
1115 else if (xerattrib->embedValues_) {
1116 switch (complaint) {
1117 case ALL_GOOD: // Not possible; present in the switch so GCC checks
1118 // that all enum values are handled (make sure there's no default).
1119 break;
1120 case NOT_SEQUENCE:
1121 case EMPTY_SEQUENCE:
1122 case FIRST_NOT_SEQOF:
1123 case SEQOF_NOT_STRING:
1124 case HAVE_DEFAULT:
1125 error("A type with EMBED-VALUES must be a sequence type. "
1126 "The first component of the sequence shall be SEQUENCE OF UTF8String "
1127 "and shall not be marked DEFAULT");
1128 break;
1129 case SEQOF_BAD_LENGTH:
1130 cf0t->error("Wrong length of SEQUENCE-OF for EMBED-VALUES, should be %lu",
1131 (unsigned long)expected_length);
1132 break;
1133 case UNTAGGED_EMBEDVAL:
1134 error("Neither the SEQUENCE-OF supporting EMBED-VALUES,"
1135 "nor its component shall have UNTAGGED."); // 25.2.2
1136 break;
1137 case UNTAGGED_OTHER:
1138 cf->error("There shall be no UNTAGGED on any character-encodable "
1139 "component of a type with DEFAULT-FOR-EMPTY"); // 25.2.3
1140 break;
1141 } // switch(complaint)
1142 } // if complaint and embedValues
1143 }
1144 /** Wraps a C string but compares by contents, not by pointer */
1145 class stringval {
1146 const char * str;
1147 public:
1148 explicit stringval(const char *s = 0) : str(s) {}
1149 // no destructor
1150 bool operator<(const stringval& right) const {
1151 if ( str > (const char*)NamespaceSpecification::ALL
1152 && right.str > (const char*)NamespaceSpecification::ALL)
1153 {
1154 return strcmp(str, right.str) < 0;
1155 }
1156 else return str < right.str;
1157 }
1158 bool operator==(const stringval& right) const {
1159 if ( str > (const char*)NamespaceSpecification::ALL
1160 && right.str > (const char*)NamespaceSpecification::ALL)
1161 {
1162 return strcmp(str, right.str) == 0;
1163 }
1164 else return str == right.str;
1165 }
1166 //bool operator!() const { return str==0; }
1167 const char *c_str() const { return str; }
1168 };
1169
1170
1171 void Type::chk_xer_text()
1172 {
1173 if (xerattrib->num_text_ == 0
1174 ||xerattrib->text_ == 0 ) FATAL_ERROR("Type::chk_xer_text()");
1175 Type * const last = get_type_refd_last();
1176 static const stringval empty; // NULL pointer
1177
1178 // Check the type and quit early if wrong
1179 switch (last->typetype) {
1180 case T_BOOL:
1181 break;
1182 case T_ENUM_A: // not yet
1183 error("No XER yet for ASN.1 enumerations");
1184 return;
1185 case T_ENUM_T:
1186 break;
1187 case T_BSTR_A: // ASN.1 bit string with named bits, not yet
1188 error("No XER yet for ASN.1 bit strings");
1189 return;
1190 case T_INT_A: // ASN.1 integer with named numbers, not yet
1191 error("No XER yet for ASN.1 named numbers");
1192 return;
1193 default:
1194 error("TEXT not allowed for type %s", get_typename().c_str());
1195 return;
1196 }
1197
1198 // Build a map to eliminate duplicates (new assignment to the same
1199 // enum item/field overwrites previous text).
1200 // Keys are the identifiers, values are the texts.
1201 typedef map<stringval, char> text_map_t;
1202 text_map_t text_map;
1203
1204 for (size_t t = 0; t < xerattrib->num_text_; ++t) {
1205 NamespaceSpecification & txt = xerattrib->text_[t];
1206 switch ((unsigned long)txt.target) {
1207 case 0: { // just "TEXT".
1208 // target=0 and new_text!=0 would have to come from "TEXT AS ..."
1209 // but that's not allowed by syntax, hence FATAL_ERROR.
1210 if (txt.new_text) FATAL_ERROR("Type::chk_xer_text");
1211 if (!text_map.has_key(empty)) {
1212 text_map.add(empty, txt.new_text);
1213 }
1214 if (last->typetype != T_BOOL) {
1215 error("Lone 'TEXT' only allowed for boolean"); // only in TTCN-3 !
1216 }
1217 break; }
1218
1219 case NamespaceSpecification::ALL: {// TEXT ALL AS ...
1220 switch (txt.keyword) {
1221 case NamespaceSpecification::NO_MANGLING:
1222 // Not possible due to syntax; there is no TTCN source from which
1223 // the bison parser would create such a NamespaceSpecification.
1224 FATAL_ERROR("Type::chk_xer_text");
1225 break;
1226 case NamespaceSpecification::CAPITALIZED:
1227 case NamespaceSpecification::UNCAPITALIZED:
1228 case NamespaceSpecification::LOWERCASED:
1229 case NamespaceSpecification::UPPERCASED:
1230 break; // OK
1231
1232 default: // TEXT ALL AS "some string" is not allowed
1233 error("text all as 'string' is not allowed");
1234 continue;
1235 } // switch(keyword)
1236
1237 // Expand the "all"
1238 switch (last->typetype) {
1239 case T_BOOL:
1240 text_map.add(stringval(mcopystr("true")), txt.new_text);
1241 text_map.add(stringval(mcopystr("false")), txt.new_text);
1242 break;
1243
1244 //case T_ENUM_A:
1245 case T_ENUM_T: {
1246 size_t n_eis = last->u.enums.eis->get_nof_eis();
1247 for (size_t i = 0; i < n_eis; ++i) {
1248 EnumItem *ei = last->u.enums.eis->get_ei_byIndex(i);
1249 const stringval enum_name(mcopystr(ei->get_name().get_ttcnname().c_str()));
1250 if (text_map.has_key(enum_name)) {
1251 // Duplicate enum name, flagged elsewhere as error.
1252 // Don't bother with: text_map[enum_name] = txt.new_text;
1253 Free(const_cast<char*>(enum_name.c_str()));
1254 }
1255 else text_map.add(enum_name, txt.new_text);
1256 }
1257 break; }
1258
1259 default:
1260 FATAL_ERROR("Type::chk_xer_text");
1261 break;
1262 } // switch (typetype)
1263 break;
1264 }
1265
1266 default: {// a string: TEXT 'member' AS ...
1267 if (txt.keyword == NamespaceSpecification::NO_MANGLING) {
1268 // Attribute syntax does not allow this combination
1269 FATAL_ERROR("Type::chk_xer_text");
1270 }
1271 // HR39956: empty string is disregarded
1272 if (txt.keyword>NamespaceSpecification::LOWERCASED && !strcmp(txt.new_text,""))
1273 {
1274 txt.new_text = (char*)Realloc(txt.new_text, sizeof(" "));
1275 strcpy(txt.new_text," ");
1276 }
1277 stringval ttarget(txt.target);
1278 if (text_map.has_key(ttarget)) {
1279 // Override the earlier TEXT instruction
1280 free_name_or_kw(text_map[ttarget]);
1281 text_map[ttarget] = txt.new_text;
1282 free_name_or_kw(txt.target);
1283 }
1284 else text_map.add(ttarget, txt.new_text);
1285 break; }
1286 } // switch(target)
1287 } // next text
1288
1289 xerattrib->text_ = (NamespaceSpecification*)Realloc(xerattrib->text_,
1290 text_map.size() * sizeof(NamespaceSpecification));
1291
1292 // Zero out the newly allocated part
1293 if (text_map.size() > xerattrib->num_text_) {
1294 memset(
1295 xerattrib->text_ + xerattrib->num_text_,
1296 0,
1297 (text_map.size() - xerattrib->num_text_) * sizeof(NamespaceSpecification)
1298 );
1299 }
1300
1301 xerattrib->num_text_ = text_map.size(); // accept the new size
1302
1303 // Another map, to check for duplicate text (decoding would be impossible)
1304 text_map_t map2;
1305
1306 // Reconstruct the TEXT structure from the map
1307 for (size_t t = 0; t < xerattrib->num_text_; ++t) {
1308 const stringval& k = text_map.get_nth_key(t);
1309 char * v = text_map.get_nth_elem(t);
1310 char * newstr = const_cast<char*>(k.c_str());
1311
1312 xerattrib->text_[t].target = newstr;
1313 xerattrib->text_[t].new_text = v;
1314
1315 stringval txtval(v); // somebody else owns v
1316 if (map2.has_key(txtval)) {
1317 switch (xerattrib->text_[t].keyword) {
1318 case NamespaceSpecification::NO_MANGLING:
1319 FATAL_ERROR("nope");
1320 break; // not possible
1321
1322 case NamespaceSpecification::CAPITALIZED:
1323 case NamespaceSpecification::UNCAPITALIZED:
1324 case NamespaceSpecification::LOWERCASED:
1325 case NamespaceSpecification::UPPERCASED:
1326 // Duplication may have been caused by expanding TEXT ALL ...
1327 break; // accept it
1328
1329 default: // string must be unique
1330 error("Duplicate text '%s'", v);
1331 break;
1332 }
1333 }
1334 else map2.add(txtval, newstr);
1335 }
1336 text_map.clear();
1337 map2.clear();
1338 // // //
1339 for (size_t t = 0; t < xerattrib->num_text_; ++t) {
1340 if (xerattrib->useNumber_) {
1341 error("USE-NUMBER and TEXT are incompatible");
1342 break;
1343 }
1344 NamespaceSpecification & txt = xerattrib->text_[t];
1345
1346 switch (last->typetype) {
1347 case T_BOOL:
1348 /* In ASN.1, Only Booleantype:ALL can have TEXT
1349 * Currently for TTCN, only the following three case are supported:
1350 * "text"
1351 * "text 'true' as '1'"
1352 * "text 'false' as '0'"
1353 * and we convert the last two to the first
1354 */
1355 switch ((unsigned long)txt.prefix) {
1356 case 0: // no Target (ok);
1357 if (txt.uri != 0) error("Only \"text\" implemented for boolean");
1358 break;
1359 case NamespaceSpecification::ALL: // Target = 'all' not allowed for boolean
1360 error("TEXT all not implemented for boolean");
1361 break;
1362 default: // a string, must be "true" or "false"
1363 if (!strcmp(txt.prefix, "true")) {
1364 // only "1" is allowed for "true"
1365 switch ((unsigned long)txt.uri) {
1366 default: // it's a string
1367 if (txt.uri[0] == '1' && txt.uri[1] == '\0') {
1368 // Free the strings to pretend it was a simple "text"
1369 Free(txt.prefix); txt.prefix = 0;
1370 Free(txt.uri); txt.uri = 0;
1371 // These should come in pairs, warn if not
1372 if (xerattrib->num_text_ == 1) warning("\"text 'false' as '0'\" was implied");
1373 break;
1374 }
1375 // else fall through
1376 case NamespaceSpecification::CAPITALIZED:
1377 case NamespaceSpecification::UNCAPITALIZED:
1378 case NamespaceSpecification::UPPERCASED:
1379 case NamespaceSpecification::LOWERCASED:
1380 error("Only '1' is supported for 'true'");
1381 break;
1382
1383 case 0: // "text 'true'" is not correct syntax, cannot get here
1384 FATAL_ERROR("Type::chk_xer_text()");
1385 } // switch uri
1386 }
1387 else if (!strcmp(txt.prefix, "false")) {
1388 // only "0" is allowed for "false"
1389 switch ((unsigned long)txt.uri) {
1390 default: // it's a string
1391 if (txt.uri[0] == '0' && txt.uri[1] == '\0') {
1392 // Free the strings to pretend it was a simple "text"
1393 Free(txt.prefix); txt.prefix = 0;
1394 Free(txt.uri); txt.uri = 0;
1395 // These should come in pairs, warn if not
1396 if (xerattrib->num_text_ == 1) warning("\"text 'true' as '1'\" was implied");
1397 break;
1398 }
1399 // else fall through
1400 case NamespaceSpecification::CAPITALIZED:
1401 case NamespaceSpecification::UNCAPITALIZED:
1402 case NamespaceSpecification::UPPERCASED:
1403 case NamespaceSpecification::LOWERCASED:
1404 error("Only '0' is supported for 'false'");
1405 break;
1406
1407 case 0: // "text 'false'" is not correct syntax, cannot get here
1408 FATAL_ERROR("Type::chk_xer_text()");
1409 } // switch uri
1410 } // if ("true")
1411 break;
1412 } // switch prefix
1413
1414 break;
1415
1416 //case T_ENUM_A: // fall through
1417 case T_ENUM_T: {
1418 switch ((unsigned long)txt.target) {
1419 case 0: // "text as ..."
1420 case NamespaceSpecification::ALL: { // "text all as ..."
1421 size_t neis = last->u.enums.eis->get_nof_eis();
1422 for (size_t i = 0; i < neis; ++i) {
1423 EnumItem *ei = last->u.enums.eis->get_ei_byIndex(i);
1424 string ei_name(ei->get_name().get_dispname()); // use the element's own name
1425 XerAttributes::NameChange chg;
1426 chg.nn_ = txt.uri;
1427 change_name(ei_name, chg);
1428 ei->set_text(ei_name);
1429 }
1430 break; }
1431
1432 default: { // target is member name, from "text 'member' as ..."
1433 // FIXME: ID_TTCN will not be right if we implement XER for ASN.1
1434 Common::Identifier id(Identifier::ID_TTCN, string(txt.prefix));
1435 if (last->u.enums.eis->get_nof_eis()==0) FATAL_ERROR("No enum items!");
1436 if (last->u.enums.eis->has_ei_withName(id)) {
1437 EnumItem *ei = last->u.enums.eis->get_ei_byName(id);
1438 string ei_name(id.get_dispname());
1439 XerAttributes::NameChange chg;
1440 chg.nn_ = txt.uri;
1441 change_name(ei_name, chg);
1442 ei->set_text(ei_name);
1443 }
1444 else {
1445 error("No enumeration item %s", txt.prefix);
1446 }
1447 break; }
1448 } // switch(target)
1449
1450 break; }
1451
1452 //case T_INT_A:
1453 /*
1454 if (last->u.namednums.nvs->get_nof_nvs()) {
1455 Common::Identifier id(Identifier::ID_TTCN, txt.uri);
1456 NamedValue *nv = last->u.namednums.nvs->get_nv_byName(id);
1457 if (nv != 0) {
1458 // good
1459 }
1460 else {
1461 error("No component %s in %s", txt.uri, fn);
1462 }
1463 }
1464 else {
1465 error("TEXT cannot be assigned to an integer without named numbers");
1466 }
1467 */
1468 //break;
1469
1470 default:
1471 FATAL_ERROR("Type::chk_xer_text");
1472 break;
1473 } // switch
1474 } // next type for TEXT
1475 }
1476
1477 void Type::chk_xer_untagged()
1478 {
1479 Type * const last = get_type_refd_last();
1480 switch (parent_type ? parent_type->typetype :-0) {
1481 case 0: // "no parent" is acceptable
1482 // Do not nag ("UNTAGGED encoding attribute is ignored on top-level type");
1483 // do it in Def_ExtFunction::chk_function_type when the type is actually
1484 // used as input for an encoding function.
1485 // fall through
1486 case T_SEQ_A: case T_SEQ_T:
1487 case T_SET_A: case T_SET_T:
1488 case T_CHOICE_A: case T_CHOICE_T:
1489 case T_SEQOF: case T_SETOF:
1490 break; // acceptable
1491 default:
1492 error("UNTAGGED can only be applied to a member of sequence, set, "
1493 "choice, sequence-of, or set-of type"); // X.693amd1, 32.2.1
1494 break;
1495 }
1496
1497 if ( has_aa(xerattrib)
1498 || has_ae(xerattrib)
1499 || xerattrib->attribute_ || 0 != xerattrib->defaultForEmpty_
1500 || xerattrib->embedValues_ || xerattrib->useNil_
1501 || (xerattrib->useOrder_ && is_asn1()) || xerattrib->useType_) {
1502 error("A type with final encoding attribute UNTAGGED shall not have"
1503 " any of the final encoding instructions ANY-ATTRIBUTES, ANY-ELEMENT,"
1504 " ATTRIBUTE, DEFAULT-FOR-EMPTY, EMBED-VALUES, PI-OR-COMMENT,"
1505 " USE-NIL%s or USE-TYPE",
1506 is_asn1() ? ", USE-ORDER" : ""); // X.693amd1, 32.2.6
1507 }
1508
1509 bool can_become_empty= last->has_empty_xml();
1510 if (can_become_empty) { // checking 32.2.4
1511 switch (parent_type ? parent_type->typetype :-0) {
1512 case 0:
1513 break; // no parent, no problem
1514
1515 case T_SEQ_A: case T_SEQ_T:
1516 case T_SET_A: case T_SET_T: {
1517 // This type can not have OPTIONAL or DEFAULT, 32.2.4 a)
1518 // No get_comp_byType(); do a linear search.
1519 size_t num_fields = parent_type->get_nof_comps();
1520 for (size_t i = 0; i < num_fields; ++i) {
1521 CompField *cf = parent_type->get_comp_byIndex(i);
1522 if (cf->get_type() != this) continue;
1523 // found the component
1524 if (cf->get_is_optional() || cf->get_defval() != 0) {
1525 error("Type with final encoding attribute UNTAGGED"
1526 " shall not have OPTIONAL or DEFAULT");
1527 }
1528 break;
1529 }
1530 break; }
1531
1532 case T_SEQOF: case T_SETOF: // X.693amd1, 32.2.4 b)
1533 error("UNTAGGED type with possibly empty XML value can not be "
1534 "the member of a sequence-of or set-of"); // X.693amd1, 32.2.4 b)
1535 break;
1536
1537 case T_CHOICE_T: {
1538 size_t num_fields = parent_type->get_nof_comps();
1539 size_t num_empty = 0;
1540 for (size_t i = 0; i < num_fields; ++i) {
1541 CompField *cf = parent_type->get_comp_byIndex(i);
1542 Type *cft = cf->get_type();
1543 if (cft->has_empty_xml()) ++num_empty;
1544 }
1545 if (num_empty > 1) { // X.693amd1, 32.2.4 c)
1546 /* FIXME: this should be error */
1547 warning("More than one alternative can be empty and has UNTAGGED");
1548 }
1549 break; }
1550
1551 default: // do nothing
1552 break;
1553 }
1554 } // end if(can_become_empty)
1555 }
1556
1557 void Type::chk_xer_use_nil()
1558 {
1559 Type * const last = get_type_refd_last();
1560
1561 enum complaint_type { ALL_GOOD, NO_CONTROLNS, NOT_SEQUENCE, EMPTY_SEQUENCE,
1562 UNTAGGED_USENIL, COMPONENT_NOT_ATTRIBUTE, LAST_IS_ATTRIBUTE,
1563 LAST_NOT_OPTIONAL, INCOMPATIBLE, WRONG_OPTIONAL_TYPE, EMBED_CHARENC,
1564 NOT_COMPATIBLE_WITH_USEORDER, BAD_ENUM, FIRST_OPTIONAL, NOTHING_TO_ORDER,
1565 FIRST_NOT_RECORD_OF_ENUM, ENUM_GAP };
1566 complaint_type complaint = ALL_GOOD;
1567 CompField *cf = 0;
1568 CompField *cf_last = 0;
1569 const char *ns, *prefix;
1570 Type *the_enum = 0;
1571 my_scope->get_scope_mod()->get_controlns(ns, prefix);
1572
1573 if (!prefix) complaint = NO_CONTROLNS; // don't bother checking further
1574 else switch (last->typetype) {
1575 default:
1576 complaint = NOT_SEQUENCE;
1577 break;
1578
1579 case T_SEQ_A:
1580 error("No XER yet for ASN.1 sequences");
1581 // no break
1582 case T_SEQ_T: {
1583 const size_t num_cf = last->get_nof_comps();
1584 if (num_cf == 0) { // 33.2.1 ...must have a component...
1585 complaint = EMPTY_SEQUENCE;
1586 break; // stop checking to prevent accessing non-existing components
1587 }
1588 if (xerattrib->untagged_) { // 33.2.2
1589 complaint = UNTAGGED_USENIL;
1590 break;
1591 }
1592
1593 // Skip components supporting USE-ORDER or EMBED-VALUES
1594 size_t i = (xerattrib->useOrder_) + (xerattrib->embedValues_);
1595 // 33.2.1 All the others except the last must be (any)attributes
1596 for (; i < num_cf-1; ++i) {
1597 cf = last->get_comp_byIndex(i);
1598 Type *cft = cf->get_type();
1599 if (! (cft->xerattrib
1600 && ( cft->xerattrib->attribute_ || has_aa(cft->xerattrib))))
1601 {
1602 complaint = COMPONENT_NOT_ATTRIBUTE;
1603 break;
1604 }
1605 }
1606 // 33.2.1 The last component must be an OPTIONAL non-attribute
1607 cf_last = last->get_comp_byIndex(num_cf-1);
1608 Type *cft = cf_last->get_type();
1609 if (!cf_last->get_is_optional()) {
1610 complaint = LAST_NOT_OPTIONAL;
1611 }
1612
1613 if(xerattrib->useOrder_ && cft->get_type_refd_last()->get_typetype() != T_SEQ_A
1614 && cft->get_type_refd_last()->get_typetype() != T_SEQ_T){
1615 complaint = NOT_COMPATIBLE_WITH_USEORDER;
1616 }else if(xerattrib->useOrder_) {
1617 //This check needed, because if the record that has useOrder only
1618 //has one field that is a sequence type, then the useNilPossible
1619 //would be always true, that would lead to incorrect code generation.
1620 Type * inner = cft->get_type_refd_last();
1621 size_t useorder_index = xerattrib->embedValues_;
1622 CompField *uo_field = last->get_comp_byIndex(useorder_index);
1623 Type *uot = uo_field->get_type();
1624 if (uot->get_type_refd_last()->typetype == T_SEQOF) {
1625 the_enum = uot->get_ofType()->get_type_refd_last();
1626 if(the_enum->typetype != T_ENUM_A && the_enum->typetype != T_ENUM_T){
1627 complaint = FIRST_NOT_RECORD_OF_ENUM;
1628 break;
1629 }else if (uo_field->get_is_optional() || uo_field->get_defval() != 0) {
1630 complaint = FIRST_OPTIONAL;
1631 break;
1632 }
1633
1634 size_t expected_enum_items = inner->get_nof_comps();
1635 size_t enum_index = 0;
1636 if (expected_enum_items == 0)
1637 complaint = NOTHING_TO_ORDER;
1638 else if (the_enum->u.enums.eis->get_nof_eis() != expected_enum_items)
1639 complaint = BAD_ENUM;
1640 else for (size_t i = 0; i < expected_enum_items; ++i) {
1641 CompField *inner_cf = inner->get_comp_byIndex(i);
1642 Type *inner_cft = inner_cf->get_type();
1643 if (inner_cft->xerattrib && inner_cft->xerattrib->attribute_) continue;
1644 // Found a non-attribute component. Its name must match an enumval
1645 const Identifier& field_name = inner_cf->get_name();
1646 const EnumItem *ei = the_enum->get_ei_byIndex(enum_index);
1647 const Identifier& enum_name = ei->get_name();
1648 if (field_name != enum_name) {// X.693amd1 35.2.2.1 and 35.2.2.2
1649 complaint = BAD_ENUM;
1650 break;
1651 }
1652 Value *v = ei->get_value();
1653 const int_val_t *ival = v->get_val_Int();
1654 const Int enumval = ival->get_val();
1655 if ((size_t)enumval != enum_index) {
1656 complaint = ENUM_GAP; // 35.2.2.3
1657 break;
1658 }
1659 ++enum_index;
1660 }
1661 }
1662 }
1663
1664 if (cft->xerattrib) {
1665 if ( cft->xerattrib->attribute_
1666 || has_aa(cft->xerattrib)) {
1667 complaint = LAST_IS_ATTRIBUTE;
1668 break;
1669 }
1670
1671 if (has_ae(cft->xerattrib)
1672 ||has_aa(cft->xerattrib)
1673 ||cft->xerattrib->defaultForEmpty_ != 0
1674 ||cft->xerattrib->untagged_
1675 ||cft->xerattrib->useNil_
1676 ||cft->xerattrib->useOrder_
1677 ||cft->xerattrib->useType_) { // or PI-OR-COMMENT
1678 complaint = INCOMPATIBLE; // 33.2.3
1679 }
1680 }
1681
1682 if (cft->is_charenc() == Yes) {
1683 // In a sequence EMBED-VALUES and USE-NIL, the optional component
1684 // supporting USE-NIL shall not be a character-encodable type.
1685 // So says OSS, and rightly so (there's no way to separate
1686 // the last field from the surrounding "embed" strings).
1687 if (xerattrib->embedValues_) complaint = EMBED_CHARENC;
1688 }
1689 else switch (cft->get_type_refd_last()->typetype) {
1690 case T_SEQ_T:
1691 // more checking
1692 case T_SEQ_A:
1693 case T_SET_T:
1694 case T_SET_A:
1695 case T_CHOICE_T:
1696 case T_CHOICE_A:
1697 case T_SEQOF:
1698 case T_SETOF:
1699 case T_OPENTYPE:
1700 // or an octetstring or bitstring with a contained "Type" and without ENCODED BY
1701 break; // acceptable
1702
1703 default:
1704 complaint = WRONG_OPTIONAL_TYPE;
1705 break;
1706 }
1707
1708 break;}
1709 } // else switch(last->typetype)
1710
1711 if (complaint == ALL_GOOD) use_nil_possible = true;
1712 else if (xerattrib->useNil_) {
1713 switch (complaint) {
1714 case ALL_GOOD: // Not possible because of the if.
1715 // Present so GCC checks that all enum values are handled (no default!)
1716 break;
1717 case NO_CONTROLNS:
1718 error("Type has USE-NIL, but the module has no control namespace set");
1719 break;
1720 case NOT_SEQUENCE:
1721 error("The target of an USE-NIL encoding instruction must be a record (SEQUENCE) or set type");
1722 break;
1723 case EMPTY_SEQUENCE:
1724 error("The target of an USE-NIL must have at least one component");
1725 break;
1726 case UNTAGGED_USENIL:
1727 error("The target of an USE-NIL encoding instruction shall not have"
1728 " a final UNTAGGED encoding instruction");
1729 break;
1730 case COMPONENT_NOT_ATTRIBUTE:
1731 cf->error("Component '%s' of USE-NIL not ATTRIBUTE", cf->get_name().get_name().c_str());
1732 break;
1733 case LAST_IS_ATTRIBUTE:
1734 cf_last->error("Last component of USE-NIL must not have ATTRIBUTE");
1735 break;
1736 case LAST_NOT_OPTIONAL:
1737 cf_last->error("Last component of USE-NIL must be OPTIONAL");
1738 break;
1739 case INCOMPATIBLE:
1740 cf_last->error("The OPTIONAL component of USE-NIL cannot have any of the "
1741 "following encoding instructions: ANY-ATTRIBUTES, ANY-ELEMENT, "
1742 "DEFAULT-FOR-EMPTY, PI-OR-COMMENT, UNTAGGED, "
1743 "USE-NIL, USE-ORDER, USE-TYPE.");
1744 break;
1745 case WRONG_OPTIONAL_TYPE:
1746 cf_last->error("The OPTIONAL component of USE-NIL must be "
1747 "a character-encodable type, or a sequence, set, choice, "
1748 "sequence-of, set-of or open type.");
1749 break;
1750 case EMBED_CHARENC:
1751 cf_last->error("In a sequence type with EMBED-VALUES and USE-NIL, "
1752 "the optional component supporting USE-NIL shall not be "
1753 "a character-encodable type.");
1754 break;
1755 case NOT_COMPATIBLE_WITH_USEORDER:
1756 cf_last->error("The OTIONAL component of USE-NIL must be "
1757 "a SEQUENCE/record when USE-ORDER is set for the parent type.");
1758 break;
1759 case BAD_ENUM:
1760 if (!the_enum) FATAL_ERROR("Type::chk_xer_use_order()");
1761 the_enum->error("Enumeration items should match the"
1762 " non-attribute components of the field %s",
1763 cf_last->get_name().get_dispname().c_str());
1764 break;
1765 case FIRST_OPTIONAL:
1766 error("The record-of for USE-ORDER shall not be marked"
1767 " OPTIONAL or DEFAULT"); // X.693amd1 35.2.3
1768 break;
1769 case NOTHING_TO_ORDER:
1770 error("The component (%s) should have at least one non-attribute"
1771 " component if USE-ORDER is present",
1772 cf_last->get_name().get_dispname().c_str());
1773 break;
1774 case FIRST_NOT_RECORD_OF_ENUM:
1775 error("The type with USE-ORDER should have a component "
1776 "which is a record-of enumerated");
1777 break;
1778 case ENUM_GAP:
1779 if (!the_enum) FATAL_ERROR("Type::chk_xer_use_order()");
1780 the_enum->error("Enumeration values must start at 0 and have no gaps");
1781 break;
1782 } // switch
1783 } // if USE-NIL
1784 }
1785
1786 void Type::chk_xer_use_order(int num_attributes)
1787 {
1788 Type * const last = get_type_refd_last();
1789
1790 enum complaint_type { ALL_GOOD, NOT_SEQUENCE, NOT_ENOUGH_MEMBERS,
1791 FIRST_NOT_RECORD_OF, FIRST_NOT_RECORD_OF_ENUM, FIRST_OPTIONAL,
1792 LAST_NOT_RECORD, BAD_ENUM, ENUM_GAP, NOTHING_TO_ORDER };
1793 complaint_type complaint = ALL_GOOD;
1794 Type *the_enum = 0; // Well, it's supposed to be an enum.
1795 switch (last->typetype) {
1796 case T_SEQ_A: case T_SEQ_T: { // record/SEQUENCE acceptable
1797 size_t useorder_index = xerattrib->embedValues_;
1798 // The first (or second, if the first is taken by EMBED_VALUES)
1799 // member must be a record of enumerated
1800 if (useorder_index >= last->get_nof_comps()) {
1801 complaint = NOT_ENOUGH_MEMBERS;
1802 break;
1803 }
1804 CompField *uo_field = last->get_comp_byIndex(useorder_index);
1805 Type *uot = uo_field->get_type();
1806 if (uot->get_type_refd_last()->typetype == T_SEQOF) {
1807 the_enum = uot->get_ofType()->get_type_refd_last();
1808 switch (the_enum->typetype) {
1809 case T_ENUM_A: case T_ENUM_T: // acceptable
1810 if (uo_field->get_is_optional() || uo_field->get_defval() != 0) {
1811 complaint = FIRST_OPTIONAL;
1812 }
1813 break;
1814 default:
1815 complaint = FIRST_NOT_RECORD_OF_ENUM;
1816 goto complain2;
1817 } // switch enum type
1818 size_t ncomps = last->get_nof_comps();
1819 // the components of this sequence will have to match the enum
1820 Type *sequence_type = 0;
1821 size_t expected_enum_items, first_non_attr;
1822
1823 if (xerattrib->useNil_) { // useNil in addition to useOrder
1824 // This is an additional complication because USE-ORDER
1825 // will affect the optional component, rather than the type itself
1826 CompField *cf = last->get_comp_byIndex(ncomps-1);
1827 sequence_type = cf->get_type()->get_type_refd_last();
1828 if (sequence_type->typetype == T_SEQ_T
1829 ||sequence_type->typetype == T_SEQ_A) {
1830
1831 // No need to check that it has at least one component (35.2.1)
1832 // it can't match up with the enum which always has one
1833 ncomps = sequence_type->get_nof_comps();
1834 expected_enum_items = ncomps;
1835 first_non_attr = 0;
1836 }
1837 else { // Whoops, not a sequence type!
1838 complaint = LAST_NOT_RECORD;
1839 break; // the switch(typetype)
1840 }
1841 }
1842 else {
1843 sequence_type = last;
1844 first_non_attr = useorder_index+1+num_attributes;
1845 expected_enum_items = ncomps - first_non_attr;
1846 } // if (use-nil)
1847
1848 size_t enum_index = 0;
1849 if (expected_enum_items == 0)
1850 complaint = NOTHING_TO_ORDER;
1851 else if (the_enum->u.enums.eis->get_nof_eis() != expected_enum_items)
1852 complaint = BAD_ENUM;
1853 else for (size_t i = first_non_attr; i < ncomps; ++i) {
1854 CompField *cf = sequence_type->get_comp_byIndex(i);
1855 Type *cft = cf->get_type();
1856 if (cft->xerattrib && cft->xerattrib->attribute_) continue;
1857 // Found a non-attribute component. Its name must match an enumval
1858 const Identifier& field_name = cf->get_name();
1859 // don't use get_eis_index_byName(); fatal error if not found :(
1860 const EnumItem *ei = the_enum->get_ei_byIndex(enum_index);
1861 const Identifier& enum_name = ei->get_name();
1862 if (field_name != enum_name) {// X.693amd1 35.2.2.1 and 35.2.2.2
1863 complaint = BAD_ENUM;
1864 break;
1865 }
1866 Value *v = ei->get_value();
1867 const int_val_t *ival = v->get_val_Int();
1868 const Int enumval = ival->get_val();
1869 if ((size_t)enumval != enum_index) {
1870 complaint = ENUM_GAP; // 35.2.2.3
1871 break;
1872 }
1873 ++enum_index;
1874 } // next enum component
1875 }
1876 else {
1877 complaint = FIRST_NOT_RECORD_OF;
1878 complain2:;
1879 }
1880 break; }
1881 default:
1882 complaint = NOT_SEQUENCE;
1883 break;
1884 } // switch typetype
1885
1886 if (complaint == ALL_GOOD) use_order_possible = true;
1887 else if (xerattrib->useOrder_) {
1888 switch (complaint) {
1889 case ALL_GOOD: // Not possible; present in the switch so GCC checks
1890 // that all enum values are handled (make sure there's no default).
1891 break;
1892 case NOT_SEQUENCE:
1893 error("USE-ORDER can only be assigned to a SEQUENCE/record type.");
1894 break;
1895 case NOT_ENOUGH_MEMBERS:
1896 case FIRST_NOT_RECORD_OF:
1897 case FIRST_NOT_RECORD_OF_ENUM:
1898 error("The type with USE-ORDER should have a component "
1899 "which is a record-of enumerated");
1900 break;
1901 case FIRST_OPTIONAL:
1902 error("The record-of for USE-ORDER shall not be marked"
1903 " OPTIONAL or DEFAULT"); // X.693amd1 35.2.3
1904 break;
1905 case NOTHING_TO_ORDER:
1906 error("The type with USE-ORDER should have at least one "
1907 "non-attribute component");
1908 break;
1909 case LAST_NOT_RECORD:
1910 error("The OPTIONAL component supporting the USE-NIL "
1911 "encoding instruction should be a SEQUENCE/record");
1912 break;
1913 case BAD_ENUM:
1914 if (!the_enum) FATAL_ERROR("Type::chk_xer_use_order()");
1915 the_enum->error("Enumeration items should match the"
1916 " non-attribute components of the sequence");
1917 break;
1918 case ENUM_GAP:
1919 if (!the_enum) FATAL_ERROR("Type::chk_xer_use_order()");
1920 the_enum->error("Enumeration values must start at 0 and have no gaps");
1921 break;
1922 } //switch
1923 } // if USE-ORDER
1924 }
1925
1926 void Type::chk_xer_use_type()
1927 {
1928 Type * const last = get_type_refd_last();
1929
1930 const char *ns, *prefix;
1931 my_scope->get_scope_mod()->get_controlns(ns, prefix);
1932 if (!prefix) error("Type has USE-TYPE, but the module has no control namespace set");
1933
1934 switch (last->typetype) {
1935 // USE-TYPE applied to anytype ? Just say no.
1936 case T_CHOICE_A: case T_CHOICE_T: { // must be CHOICE; 37.2.1
1937 if (xerattrib->untagged_ || xerattrib->useUnion_) { // 37.2.5
1938 error("A type with USE-TYPE encoding instruction shall not also have"
1939 " any of the final encoding instructions UNTAGGED or USE-UNION");
1940 }
1941 // Now check the alternatives.
1942 // iterating backwards calls get_nof_comps only once
1943 for (int i = last->get_nof_comps() - 1; i >= 0; --i) {
1944 CompField *cf = last->get_comp_byIndex(i);
1945 Type *cft = cf->get_type();
1946 if (cft->xerattrib && cft->xerattrib->untagged_) {
1947 cf->error("Alternative of a union with USE-TYPE should not have UNTAGGED"); // 37.2.2
1948 break;
1949 }
1950 switch (cft->typetype) {
1951 case T_CHOICE_A: case T_CHOICE_T:
1952 if (cft->xerattrib && cft->xerattrib->useType_) {
1953 cf->error("Alternative of a CHOICE type with USE-TYPE shall not be"
1954 " a CHOICE type with a USE-TYPE encoding instruction"); // 37.2.3
1955 }
1956 break;
1957 default:
1958 break;
1959 }
1960 }
1961 break; }
1962 default:
1963 error("USE-TYPE can only applied to a CHOICE/union type");
1964 break;
1965 } // switch
1966 }
1967
1968 void Type::chk_xer_use_union()
1969 {
1970 Type * const last = get_type_refd_last();
1971 switch (last->typetype) {
1972 case T_CHOICE_A: case T_CHOICE_T: {
1973 // Now check the alternatives.
1974 // iterating backwards calls get_nof_comps only once
1975 for (int i = last->get_nof_comps() - 1; i >= 0; --i) {
1976 CompField *cf = last->get_comp_byIndex(i);
1977 Type *cft = cf->get_type();
1978 if (cft->is_charenc() && !(cft->xerattrib && cft->xerattrib->useType_) &&
1979 !(cft->xerattrib && cft->xerattrib->useQName_)) { // currently not supported
1980 if (cft->xerattrib && cft->xerattrib->useUnion_) // it must be a union
1981 cf->error("Alternative of a CHOICE/union with USE-UNION"
1982 " can not itself be a CHOICE/union with USE-UNION");
1983 }
1984 else cf->error("Alternative of a CHOICE/union with USE-UNION must be character-encodable");
1985 }
1986 break; }
1987 default:
1988 error("USE-UNION can only applied to a CHOICE/union type"); // 38.2.1
1989 break;
1990 }
1991
1992 }
1993
1994 static const char *xml98 = "http://www.w3.org/XML/1998/namespace";
1995
1996 void Type::chk_xer() { // XERSTUFF semantic check
1997 // the type (and everything it contains) is fully checked now
1998
1999 if (xer_checked) return;
2000 xer_checked = true;
2001
2002 Type *last = get_type_refd_last();
2003
2004 // Check XER attributes if the type belongs to a type definition,
2005 // a field of a record/set/union, or is the embedded type of a record-of.
2006 if (ownertype==OT_TYPE_DEF
2007 ||ownertype==OT_COMP_FIELD
2008 ||ownertype==OT_RECORD_OF) {
2009 XerAttributes *newx = 0;
2010 if (is_ref()) {
2011 // Merge XER attributes from the referenced type.
2012 // This implements X.693amd1 clause 15.1.2
2013 newx = new XerAttributes;
2014 Type *t1 = get_type_refd();
2015 // chk_refd() (called by chk() for T_REFD) does not check
2016 // the referenced type; do it now. This makes it fully recursive.
2017 t1->chk();
2018
2019 size_t old_text = 0;
2020 if (t1->xerattrib && !t1->xerattrib->empty()) {
2021 old_text = t1->xerattrib->num_text_;
2022 *newx |= *t1->xerattrib; // get the ancestor's attributes, except...
2023 newx->attribute_ = false; // attribute is not inherited
2024 newx->element_ = false; // element is not inherited
2025
2026 if (ownertype == OT_TYPE_DEF
2027 ||ownertype == OT_COMP_FIELD) {
2028 // Name,Namespace is not inherited, X.693 amd1, 13.6
2029 // are you sure about the namespace?
2030 XerAttributes::FreeNameChange(newx->name_);
2031 //XerAttributes::FreeNamespace(newx->namespace_); // HR39678 bugfix beta
2032 }
2033 }
2034 // Now merge/override with our own attributes
2035 if (xerattrib && !xerattrib->empty()) {
2036 if (xerattrib->num_text_ > 0 && old_text > 0
2037 && (last->typetype == T_ENUM_T || last->typetype == T_ENUM_A)) {
2038 // Adding more TEXT attributes does not work right.
2039 error("Adding more TEXT attributes is not supported "
2040 "by the implementation.");
2041 }
2042 *newx |= *xerattrib;
2043 }
2044
2045 if (newx->empty()) delete newx;
2046 else { // something interesting was found
2047 delete xerattrib;
2048 xerattrib = newx;
2049
2050 if (xerattrib->attribute_
2051 && t1->xerattrib && t1->xerattrib->attribute_
2052 && t1->ownertype == OT_TYPE_DEF
2053 && !(xerattrib->form_ & XerAttributes::LOCALLY_SET) ) {
2054 // The referenced type came from a global XSD attribute.
2055 // This type's form will be qualified, unless it has an explicit
2056 // "form as ..." (which overrides everything).
2057 xerattrib->form_ |= XerAttributes::QUALIFIED;
2058 }
2059
2060 if (t1->xerattrib && t1->xerattrib->element_
2061 // The referenced type came from a global XSD element.
2062 && !(xerattrib->form_ & XerAttributes::LOCALLY_SET))
2063 { // and it doesn't have an explicit "form as ..."
2064 xerattrib->form_ |= XerAttributes::QUALIFIED;
2065 }
2066 }
2067 } // if is_ref
2068 } // if ownertype
2069
2070 if (!xerattrib) return;
2071
2072 //const char *fn = get_fullname().c_str();
2073 //printf("chk_xer(%s)\n", fn);
2074
2075 // In general, "last" should be used instead of "this" in the checks below
2076 // when accessing information about the type's characteristics, except
2077 // this->xerattrib MUST be used (and not last->xerattrib!).
2078
2079 switch (ownertype) {
2080 case OT_COMP_FIELD:
2081 case OT_TYPE_DEF:
2082 case OT_RECORD_OF:
2083 // acceptable
2084 break;
2085
2086 default:
2087 FATAL_ERROR("Unexpected ownertype %d", ownertype);
2088 }
2089
2090 int num_attributes = 0;
2091 switch (last->typetype) {
2092 case T_SEQ_A: case T_SEQ_T:
2093 case T_SET_A: case T_SET_T: {
2094 // Count attributes (ANY-ATTRIBUTES counts as one)
2095 const size_t num_cf = last->get_nof_comps();
2096 int specials = xerattrib->embedValues_ + xerattrib->useOrder_;
2097 int num_any_attributes = 0;
2098 for (int x = num_cf - 1; x >= specials; --x) {
2099 CompField *cf = last->get_comp_byIndex(x);
2100 Type *cft = cf->get_type() /* NOT get_type_refd_last() */;
2101 if (cft->xerattrib
2102 && (cft->xerattrib->attribute_ || has_aa(cft->xerattrib)))
2103 {
2104 if (cft->xerattrib->attribute_) ++num_attributes;
2105 else if (++num_any_attributes > 1) {
2106 cf->error("There can be at most one field with ANY-ATTRIBUTES");
2107 }
2108 }
2109 else if (num_attributes + num_any_attributes > 0) {
2110 // Found a non-attribute when there was an attribute after it
2111 cf->error("Non-attribute field before attribute not supported");
2112 }
2113 } // next
2114
2115 num_attributes += num_any_attributes;
2116 break; }
2117
2118 default:
2119 break;
2120 }
2121
2122 /* * * Check restrictions set out in X.693 amd1, clauses 18-39 * * */
2123
2124 if (has_aa(xerattrib)) {
2125 chk_xer_any_attributes();
2126 } // if ANY-ATTRIBUTES
2127
2128 if (has_ae(xerattrib)) {
2129 chk_xer_any_element();
2130 } // if ANY-ELEMENT
2131
2132 if (xerattrib->attribute_) {
2133 chk_xer_attribute();
2134 // It's an attribute, check for the attributeFormQualified bit
2135 // and transform it into unconditionally qualified.
2136 if (!(xerattrib->form_ & XerAttributes::LOCALLY_SET)
2137 && (xerattrib->form_ & XerAttributes::ATTRIBUTE_DEFAULT_QUALIFIED)) {
2138 xerattrib->form_ |= XerAttributes::QUALIFIED;
2139 }
2140 }
2141 else {
2142 // Element, check the elementFormQualified bit.
2143 if (!(xerattrib->form_ & XerAttributes::LOCALLY_SET)
2144 && (xerattrib->form_ & XerAttributes::ELEMENT_DEFAULT_QUALIFIED)) {
2145 xerattrib->form_ |= XerAttributes::QUALIFIED;
2146 }
2147 } // if ATTRIBUTE
2148
2149 if (xerattrib->base64_) {
2150 switch (last->typetype) {
2151 case T_OSTR: // OCTET STRING
2152 case T_HSTR: // hexstring
2153 case T_OPENTYPE:
2154 case T_BMPSTRING:
2155 case T_GENERALSTRING:
2156 case T_GRAPHICSTRING:
2157 case T_IA5STRING:
2158 // ISO646String ?
2159 case T_NUMERICSTRING:
2160 case T_PRINTABLESTRING:
2161 case T_TELETEXSTRING:
2162 // T61
2163 case T_UNIVERSALSTRING:
2164 case T_UTF8STRING:
2165 case T_VIDEOTEXSTRING:
2166 case T_VISIBLESTRING:
2167 // TTCN types
2168 case T_CSTR:
2169 case T_USTR:
2170 break; // acceptable
2171 default:
2172 error("BASE64 can only be applied to OCTET STRING, open type or "
2173 "restricted character string type");
2174 break;
2175 } // switch
2176
2177 if (has_ae(xerattrib) || xerattrib->whitespace_ != XerAttributes::PRESERVE) {
2178 error("A type with BASE64 shall not have any of the final "
2179 "encoding instructions ANY-ELEMENT or WHITESPACE");
2180 }
2181 } // if BASE64
2182
2183 if (xerattrib->decimal_) {
2184 if (last->typetype != T_REAL) {
2185 error("DECIMAL shall only be assigned to a real type");
2186 }
2187 } // if DECIMAL
2188
2189 if (xerattrib->defaultForEmpty_ != 0) {
2190 chk_xer_dfe();
2191 } // if defaultForEmpty
2192
2193 chk_xer_embed_values(num_attributes); // always
2194
2195 if (xerattrib->list_) {
2196 switch (last->typetype) {
2197 case T_SEQOF: case T_SETOF:
2198 break; // acceptable
2199 default:
2200 error("LIST can only be assigned to SEQUENCE-OF or SET-OF");// 27.2.1
2201 break;
2202 }
2203
2204 if (has_aa(xerattrib)) {
2205 error("A type with LIST shall not have ANY-ATTRIBUTES");// 27.2.3
2206 }
2207 } // if LIST
2208
2209 // NAME is handled later when generate_code_xerdescriptor call change_name
2210
2211 if ((unsigned long)xerattrib->namespace_.keyword
2212 > (unsigned long)NamespaceSpecification::LOWERCASED) {
2213 // Now both are proper non-NULL strings
2214 if (*xerattrib->namespace_.prefix != 0) { // there is a prefix, check it
2215 char first[4] = {0,0,0,0};
2216 strncpy(first, xerattrib->namespace_.prefix, 3);
2217 first[0] = toupper(first[0]);
2218 first[1] = toupper(first[1]);
2219 first[2] = toupper(first[2]);
2220 if (!memcmp(first, "XML", 3) // It _is_ "xml"
2221 // but the W3C XML namespace gets an exemption
2222 && strcmp(xerattrib->namespace_.uri, xml98)) error(
2223 "Prefix shall not commence with characters that"
2224 " when uppercased are 'XML'");
2225 // X.693 (11/2008), clause 29.1.7
2226 }
2227
2228 Common::Module::add_namespace(
2229 xerattrib->namespace_.uri, xerattrib->namespace_.prefix);
2230 }
2231 else xerattrib->namespace_.uri = NULL; // really no namespace
2232
2233 // PI-OR-COMMENT not supported
2234
2235 if (xerattrib->num_text_ > 0) {
2236 chk_xer_text();
2237 }
2238
2239 if (xerattrib->untagged_) {
2240 chk_xer_untagged();
2241 } // if UNTAGGED
2242
2243 chk_xer_use_nil(); // always
2244
2245 if (xerattrib->useNumber_) {
2246 switch (last->typetype) {
2247 case T_ENUM_A:
2248 error("No XER yet for ASN.1 enumerations");
2249 // no break
2250 case T_ENUM_T:
2251 break; // acceptable
2252 default:
2253 warning("USE-NUMBER ignored unless assigned to an enumerated type");
2254 xerattrib->useNumber_ = false;
2255 break;
2256 }
2257
2258 if (xerattrib->num_text_) {
2259 error("A type with USE-NUMBER shall not have TEXT");
2260 }
2261 } // if USE-NUMBER
2262
2263 chk_xer_use_order(num_attributes); //always
2264
2265 if (xerattrib->useQName_) {
2266 switch (last->typetype) {
2267 case T_SEQ_A: case T_SEQ_T: {
2268 if (last->get_nof_comps() != 2) goto complain;
2269 const CompField * cf = last->get_comp_byIndex(0);
2270 const Type * cft = cf->get_type()->get_type_refd_last();
2271 if (cft->typetype != T_USTR && cft->typetype != T_UTF8STRING)
2272 cft->error ("Both components must be UTF8String or universal charstring");
2273 if (!cf->get_is_optional()) cft->error(
2274 "The first component of a type with USE-QNAME must be optional");
2275
2276 cf = last->get_comp_byIndex(1);
2277 cft = cf->get_type()->get_type_refd_last();
2278 if (cft->typetype != T_USTR && cft->typetype != T_UTF8STRING)
2279 cft->error ("Both components must be UTF8String or universal charstring");
2280 if (cf->get_is_optional()) cft->error(
2281 "The second component of a type with USE-QNAME must NOT be optional");
2282 break; }
2283
2284 default:
2285 complain:
2286 error("A type with USE-QNAME must be a sequence type with exactly two components.");
2287 break;
2288 }
2289 if (xerattrib->useNil_) error("A type with USE-QNAME shall not have USE-NIL"); // 36.2.4
2290 }
2291
2292 if (xerattrib->useType_) {
2293 chk_xer_use_type();
2294 } // if USE-TYPE
2295
2296 if (xerattrib->useUnion_) {
2297 chk_xer_use_union();
2298 }
2299
2300 if (is_secho()) {
2301 CompFieldMap& cfm = *u.secho.cfm;
2302 const size_t ncomps = cfm.get_nof_comps();
2303 CompField *the_one = 0; // ...and only untagged character-encodable field
2304 map<int, CompField> empties; // potentially empties
2305
2306 for (size_t i=0; i < ncomps; ++i) {
2307 CompField * cf = cfm.get_comp_byIndex(i);
2308 Type *cft = cf->get_type();
2309
2310 if (cft->xerattrib && cft->xerattrib->untagged_) {
2311 /* This check could be in chk_xer_untagged(), but then we couldn't
2312 * access the CompField in the parent type. */
2313 if (cft->is_charenc() == Yes) {
2314 if (the_one) { // already has one
2315 cf->error("More than one UNTAGGED character-encodable field");
2316 // break? to report only once
2317 }
2318 else {
2319 the_one = cf; // this is used for further checks below
2320 u.secho.has_single_charenc = true; // used while generating code
2321 switch (typetype) {
2322 case T_SEQ_A: case T_SEQ_T:
2323 if (xerattrib->untagged_) {
2324 error("Enclosing type of an UNTAGGED character-encodable type "
2325 "must not be UNTAGGED");
2326 }
2327 break; // the small switch
2328 default:
2329 error("Enclosing type of an UNTAGGED character-encodable type "
2330 "is not record.");
2331 break;
2332 } // switch
2333 } // if (the_one)
2334 }
2335 else { // untagged, not charenc
2336 switch (cft->get_type_refd_last()->typetype) {
2337 case T_SEQ_A: case T_SEQ_T:
2338 case T_SET_A: case T_SET_T:
2339 case T_CHOICE_A: case T_CHOICE_T:
2340 case T_SEQOF:
2341 case T_SETOF:
2342 //case T_OSTR: with a contained type
2343 //case T_BSTR_A: with a contained type
2344 //case T_OPENTYPE:
2345 break; //ok
2346
2347 default: // 32.2.3 "If the type is not character-encodable..."
2348 cft->error("UNTAGGED type should be sequence, set, choice, sequence-of, or set-of type");
2349 break;
2350 }
2351 } // if(is_charenc)
2352 } // if untagged
2353
2354 if (cft->has_empty_xml()) {
2355 empties.add(i, cf);
2356 }
2357 } // next component
2358
2359 if (the_one) {
2360 if (the_one->get_is_optional() || the_one->has_default()) {
2361 the_one->error("UNTAGGED field should not be marked OPTIONAL or DEFAULT");
2362 }
2363 // Check the other compfields. They must all be (ANY)?ATTRIBUTE
2364 for (size_t i=0; i < ncomps; ++i) {
2365 CompField *cf = cfm.get_comp_byIndex(i);
2366 if (cf == the_one) continue;
2367
2368 Type *cft = cf->get_type();
2369 if ( !cft->xerattrib // cannot be attribute, error
2370 || (!cft->xerattrib->attribute_ && !has_aa(cft->xerattrib))) {
2371 the_one->note("Due to this UNTAGGED component");
2372 cf->error("All the other components should be ATTRIBUTE or ANY-ATTRIBUTE");
2373 // X.693 (2008) 32.2.2
2374 break;
2375 }
2376 } // next i
2377 } // if the_one
2378
2379 if (empties.size() > 1
2380 && (typetype==T_CHOICE_A || typetype==T_CHOICE_T)) {
2381 warning("More than one field can have empty XML. Decoding of empty"
2382 " XML is ambiguous, %s chosen arbitrarily.",
2383 empties.get_nth_elem(empties.size()-1)->get_name().get_name().c_str());
2384 }
2385 empties.clear();
2386 } // if secho
2387
2388 if (xerattrib->abstract_ || xerattrib->block_) {
2389 switch (ownertype) {
2390 case OT_COMP_FIELD:
2391 if (parent_type->typetype == T_CHOICE_A ||
2392 parent_type->typetype == T_CHOICE_T) {
2393 if (parent_type->xerattrib != NULL && parent_type->xerattrib->useUnion_) {
2394 error("ABSTRACT and BLOCK cannot be used on fields of a union with "
2395 "attribute USE-UNION.");
2396 }
2397 break;
2398 }
2399 // else fall through
2400 case OT_RECORD_OF:
2401 case OT_TYPE_DEF:
2402 warning("ABSTRACT and BLOCK only affects union fields.");
2403 break;
2404 default:
2405 break;
2406 }
2407 }
2408
2409 }
2410
2411
2412 void Type::chk_Int_A()
2413 {
2414 if(checked) return;
2415 checked=true;
2416 if(!u.namednums.block) return;
2417 parse_block_Int();
2418 if(typetype==T_ERROR) return;
2419 /* check named numbers */
2420 if(!u.namednums.nvs) return;
2421 map<Int, NamedValue> value_map;
2422 Error_Context cntxt(this, "In named numbers");
2423 u.namednums.nvs->chk_dupl_id();
2424 for (size_t i = 0; i < u.namednums.nvs->get_nof_nvs(); i++) {
2425 NamedValue *nv = u.namednums.nvs->get_nv_byIndex(i);
2426 Value *value = nv->get_value();
2427 Value *v = value->get_value_refd_last();
2428 switch (v->get_valuetype()) {
2429 case Value::V_INT: {
2430 const int_val_t *int_val_int = v->get_val_Int();
2431 if (*int_val_int > INT_MAX) {
2432 value->error("Integer value `%s' is too big to be used as a named "
2433 "number", (int_val_int->t_str()).c_str());
2434 } else {
2435 Int int_val = int_val_int->get_val();
2436 if (value_map.has_key(int_val)) {
2437 value->error("Duplicate number %s for name `%s'",
2438 Int2string(int_val).c_str(),
2439 nv->get_name().get_dispname().c_str());
2440 NamedValue *nv2 = value_map[int_val];
2441 nv2->note("Number %s is already assigned to name `%s'",
2442 Int2string(int_val).c_str(),
2443 nv2->get_name().get_dispname().c_str());
2444 } else {
2445 value_map.add(int_val, nv);
2446 }
2447 }
2448 break; }
2449 case Value::V_ERROR:
2450 break;
2451 default:
2452 nv->error("INTEGER value was expected for named number `%s'",
2453 nv->get_name().get_dispname().c_str());
2454 break;
2455 }
2456 }
2457 value_map.clear();
2458 }
2459
2460 void Type::chk_Enum_A()
2461 {
2462 if(checked) return;
2463 if(!u.enums.block) return;
2464 parse_block_Enum();
2465 if(typetype==T_ERROR) return;
2466 /* checking enumerations */
2467 map<Int, EnumItem> value_map;
2468 /* checking values before the ellipsis */
2469 for (size_t i = 0; i < u.enums.eis1->get_nof_eis(); i++)
2470 chk_Enum_item(u.enums.eis1->get_ei_byIndex(i), false, value_map);
2471 /* assigning default values */
2472 Int& first_unused = u.enums.first_unused;
2473 for (first_unused = 0; value_map.has_key(first_unused); first_unused++) ;
2474 for (size_t i = 0; i < u.enums.eis1->get_nof_eis(); i++) {
2475 EnumItem *ei = u.enums.eis1->get_ei_byIndex(i);
2476 if (!ei->get_value()) {
2477 ei->set_value(new Value(Value::V_INT, first_unused));
2478 value_map.add(first_unused, ei);
2479 while (value_map.has_key(++first_unused)) ;
2480 }
2481 }
2482 /* checking values after the ellipsis */
2483 if(u.enums.eis2) {
2484 for(size_t i=0; i < u.enums.eis2->get_nof_eis(); i++)
2485 chk_Enum_item(u.enums.eis2->get_ei_byIndex(i), true, value_map);
2486 }
2487 /* determining the first two unused non-negative integer values
2488 * for code generation */
2489 for (first_unused = 0; value_map.has_key(first_unused); first_unused++) ;
2490 Int& second_unused = u.enums.second_unused;
2491 for (second_unused = first_unused + 1; value_map.has_key(second_unused);
2492 second_unused++) ;
2493 value_map.clear();
2494 u.enums.eis1->release_eis();
2495 delete u.enums.eis1;
2496 u.enums.eis1 = 0;
2497 if(u.enums.eis2) {
2498 u.enums.eis2->release_eis();
2499 delete u.enums.eis2;
2500 u.enums.eis2 = 0;
2501 }
2502 }
2503
2504 void Type::chk_Enum_item(EnumItem *ei, bool after_ellipsis,
2505 map<Int, EnumItem>& value_map)
2506 {
2507 const Identifier& name = ei->get_name();
2508 const char *dispname_str = name.get_dispname().c_str();
2509 if (u.enums.eis->has_ei_withName(name)) {
2510 ei->error("Duplicate ENUMERATED identifier: `%s'", dispname_str);
2511 u.enums.eis->get_ei_byName(name)->note("Previous definition of `%s' "
2512 "is here", dispname_str);
2513 } else if (!name.get_has_valid(Identifier::ID_TTCN)) {
2514 ei->warning("The identifier `%s' is not reachable from TTCN-3",
2515 dispname_str);
2516 }
2517 u.enums.eis->add_ei(ei);
2518 Int& first_unused=u.enums.first_unused;
2519 Value *value = ei->get_value();
2520 if (value) {
2521 Value *v;
2522 {
2523 Error_Context cntxt(ei, "In enumeration `%s'", dispname_str);
2524 v = value->get_value_refd_last();
2525 }
2526 switch (v->get_valuetype()) {
2527 case Value::V_INT:
2528 break;
2529 case Value::V_ERROR:
2530 return;
2531 default:
2532 value->error("INTEGER value was expected for enumeration `%s'",
2533 dispname_str);
2534 return;
2535 }
2536 Int enum_value = v->get_val_Int()->get_val();
2537 if (static_cast<Int>(static_cast<int>(enum_value)) != enum_value) {
2538 value->error("The numeric value of enumeration `%s' (%s) is too "
2539 "large for being represented in memory", dispname_str,
2540 Int2string(enum_value).c_str());
2541 }
2542 if (after_ellipsis) {
2543 if (enum_value >= first_unused) {
2544 value_map.add(enum_value, ei);
2545 for (first_unused = enum_value + 1; value_map.has_key(first_unused);
2546 first_unused++) ;
2547 } else {
2548 value->error("ENUMERATED values shall be monotonically growing after "
2549 "the ellipsis: the value of `%s' must be at least %s instead of %s",
2550 dispname_str, Int2string(first_unused).c_str(),
2551 Int2string(enum_value).c_str());
2552 }
2553 } else {
2554 if (value_map.has_key(enum_value)) {
2555 value->error("Duplicate numeric value %s for enumeration `%s'",
2556 Int2string(enum_value).c_str(), dispname_str);
2557 EnumItem *ei2 = value_map[enum_value];
2558 ei2->note("Value %s is already assigned to `%s'",
2559 Int2string(enum_value).c_str(),
2560 ei2->get_name().get_dispname().c_str());
2561 } else value_map.add(enum_value, ei);
2562 }
2563 } else { // the item has no value
2564 if (after_ellipsis) {
2565 ei->set_value(new Value(Value::V_INT, first_unused));
2566 value_map.add(first_unused, ei);
2567 while (value_map.has_key(++first_unused)) ;
2568 }
2569 }
2570 }
2571
2572 void Type::chk_Enum_T()
2573 {
2574 if(checked) return;
2575 map<Int, EnumItem> value_map;
2576 map<string, EnumItem> name_map;
2577 bool error_flag = false;
2578 /* checking the uniqueness of identifiers and values */
2579 size_t nof_eis = u.enums.eis->get_nof_eis();
2580 for(size_t i = 0; i < nof_eis; i++) {
2581 EnumItem *ei = u.enums.eis->get_ei_byIndex(i);
2582 const Identifier& id = ei->get_name();
2583 const string& name = id.get_name();
2584 if (name_map.has_key(name)) {
2585 const char *dispname_str = id.get_dispname().c_str();
2586 ei->error("Duplicate enumeration identifier `%s'", dispname_str);
2587 name_map[name]->note("Previous definition of `%s' is here",
2588 dispname_str);
2589 error_flag = true;
2590 } else {
2591 name_map.add(name, ei);
2592 }
2593 Value *value = ei->get_value();
2594 if (value) {
2595 /* Handle the error node created by the parser. */
2596 if (value->get_valuetype() == Value::V_ERROR) {
2597 value->error("INTEGER value was expected for enumeration `%s'",
2598 id.get_dispname().c_str());
2599 error_flag = true;
2600 } else {
2601 const int_val_t *enum_value_int = value->get_val_Int();
2602 // It used to be the same check.
2603 if (*enum_value_int > INT_MAX ||
2604 static_cast<Int>(static_cast<int>(enum_value_int->get_val()))
2605 != enum_value_int->get_val()) {
2606 value->error("The numeric value of enumeration `%s' (%s) is "
2607 "too large for being represented in memory",
2608 id.get_dispname().c_str(), (enum_value_int->t_str()).c_str());
2609 error_flag = true;
2610 } else {
2611 Int enum_value = enum_value_int->get_val();
2612 if (value_map.has_key(enum_value)) {
2613 const char *dispname_str = id.get_dispname().c_str();
2614 value->error("Duplicate numeric value %s for enumeration `%s'",
2615 Int2string(enum_value).c_str(), dispname_str);
2616 EnumItem *ei2 = value_map[enum_value];
2617 ei2->note("Value %s is already assigned to `%s'",
2618 Int2string(enum_value).c_str(),
2619 ei2->get_name().get_dispname().c_str());
2620 error_flag = true;
2621 } else {
2622 value_map.add(enum_value, ei);
2623 }
2624 }
2625 }
2626 }
2627 }
2628 if (!error_flag) {
2629 /* assigning default values */
2630 Int& first_unused=u.enums.first_unused;
2631 for(first_unused=0; value_map.has_key(first_unused); first_unused++) ;
2632 for(size_t i = 0; i < nof_eis; i++) {
2633 EnumItem *ei = u.enums.eis->get_ei_byIndex(i);
2634 if(!ei->get_value()) {
2635 ei->set_value(new Value(Value::V_INT, first_unused));
2636 value_map.add(first_unused, ei);
2637 while (value_map.has_key(++first_unused)) ;
2638 }
2639 }
2640 Int& second_unused = u.enums.second_unused;
2641 for (second_unused = first_unused + 1; value_map.has_key(second_unused);
2642 second_unused++) ;
2643 }
2644 value_map.clear();
2645 name_map.clear();
2646 }
2647
2648 void Type::chk_BStr_A()
2649 {
2650 if(!u.namednums.block) return;
2651 parse_block_BStr();
2652 if(typetype==T_ERROR) return;
2653 if(u.namednums.nvs) {
2654 /* check named bits */
2655 map<Int, NamedValue> value_map;
2656 {
2657 Error_Context cntxt(this, "In named bits");
2658 u.namednums.nvs->chk_dupl_id();
2659 }
2660 for(size_t i = 0; i < u.namednums.nvs->get_nof_nvs(); i++) {
2661 NamedValue *nv = u.namednums.nvs->get_nv_byIndex(i);
2662 const char *dispname_str = nv->get_name().get_dispname().c_str();
2663 Value *value = nv->get_value();
2664 Value *v;
2665 {
2666 Error_Context cntxt(this, "In named bit `%s'", dispname_str);
2667 v = value->get_value_refd_last();
2668 }
2669 switch (v->get_valuetype()) {
2670 case Value::V_INT:
2671 break;
2672 case Value::V_ERROR:
2673 continue;
2674 default:
2675 v->error("INTEGER value was expected for named bit `%s'",
2676 dispname_str);
2677 continue;
2678 }
2679 const int_val_t *int_val_int = v->get_val_Int();
2680 if (*int_val_int > INT_MAX) {
2681 value->error("An INTEGER value less than `%d' was expected for "
2682 "named bit `%s' instead of %s", INT_MAX, dispname_str,
2683 (int_val_int->t_str()).c_str());
2684 continue;
2685 }
2686 Int int_val = int_val_int->get_val();
2687 if(int_val < 0) {
2688 value->error("A non-negative INTEGER value was expected for named "
2689 "bit `%s' instead of %s", dispname_str,
2690 Int2string(int_val).c_str());
2691 continue;
2692 }
2693 if (value_map.has_key(int_val)) {
2694 value->error("Duplicate value %s for named bit `%s'",
2695 Int2string(int_val).c_str(), dispname_str);
2696 NamedValue *nv2 = value_map[int_val];
2697 nv2->note("Bit %s is already assigned to name `%s'",
2698 Int2string(int_val).c_str(),
2699 nv2->get_name().get_dispname().c_str());
2700 } else value_map.add(int_val, nv);
2701 }
2702 value_map.clear();
2703 }
2704 }
2705
2706 void Type::chk_SeCho_T()
2707 {
2708 u.secho.cfm->set_my_type(this);
2709 checked = true;
2710 u.secho.cfm->chk();
2711 u.secho.component_internal = false;
2712 size_t nof_comps = u.secho.cfm->get_nof_comps();
2713 for (size_t i=0; i<nof_comps; i++) {
2714 Type* cft = u.secho.cfm->get_comp_byIndex(i)->get_type();
2715 if (cft && cft->is_component_internal()) {
2716 u.secho.component_internal = true;
2717 break;
2718 }
2719 }
2720 }
2721
2722 void Type::chk_Choice_A()
2723 {
2724 if(u.secho.block) parse_block_Choice();
2725 if(typetype==T_ERROR) return;
2726 checked=true;
2727 if(u.secho.ctss->needs_auto_tags())
2728 u.secho.ctss->add_auto_tags();
2729 u.secho.ctss->chk();
2730 if (u.secho.ctss->get_nof_comps() <= 0)
2731 FATAL_ERROR("CHOICE type must have at least one alternative");
2732 u.secho.ctss->chk_tags();
2733 }
2734
2735 void Type::chk_Se_A()
2736 {
2737 if(u.secho.block) parse_block_Se();
2738 if(typetype==T_ERROR) return;
2739 checked=true;
2740 tr_compsof();
2741 u.secho.ctss->chk();
2742 u.secho.ctss->chk_tags();
2743 }
2744
2745 void Type::chk_SeOf()
2746 {
2747 u.seof.ofType->set_genname(get_genname_own(), string('0'));
2748 u.seof.ofType->set_parent_type(this);
2749 checked=true;
2750 const char *type_name;
2751 bool asn1 = is_asn1();
2752 switch (typetype) {
2753 case T_SEQOF:
2754 type_name = asn1 ? "SEQUENCE OF" : "record of";
2755 break;
2756 case T_SETOF:
2757 type_name = asn1 ? "SET OF" : "set of";
2758 break;
2759 default:
2760 type_name = "<unknown>";
2761 break;
2762 }
2763 Error_Context cntxt(this, "In embedded type of %s", type_name);
2764 u.seof.ofType->chk();
2765 if (!asn1) u.seof.ofType->chk_embedded(true, "embedded into another type");
2766 u.seof.component_internal = u.seof.ofType->is_component_internal();
2767 }
2768
2769 void Type::chk_refd()
2770 {
2771 checked=true;
2772 ReferenceChain refch(this, "While checking referenced type");
2773 Type* t_last = get_type_refd_last(&refch);
2774 u.ref.component_internal = t_last->is_component_internal();
2775 }
2776
2777 void Type::chk_seltype()
2778 {
2779 checked=true;
2780 u.seltype.type->set_genname(get_genname_own(), string('0'));
2781 ReferenceChain refch(this, "In selection type");
2782 get_type_refd_last(&refch);
2783 if(typetype==T_ERROR) return;
2784 u.seltype.type->chk();
2785 }
2786
2787 void Type::chk_Array()
2788 {
2789 u.array.element_type->set_genname(get_genname_own(), string('0'));
2790 u.array.element_type->set_parent_type(this);
2791 checked = true;
2792 {
2793 Error_Context cntxt(this, "In element type of array");
2794 u.array.element_type->chk();
2795 u.array.element_type->chk_embedded(true, "embedded into an array type");
2796 }
2797 u.array.dimension->chk();
2798 u.array.component_internal = u.array.element_type->is_component_internal();
2799 }
2800
2801 void Type::chk_Signature()
2802 {
2803 checked = true;
2804 u.signature.component_internal = false;
2805 if (u.signature.parameters) {
2806 u.signature.parameters->chk(this);
2807 size_t nof_params = u.signature.parameters->get_nof_params();
2808 for (size_t i=0; i<nof_params; i++) {
2809 Type* spt = u.signature.parameters->get_param_byIndex(i)->get_type();
2810 if (spt && spt->is_component_internal()) {
2811 u.signature.component_internal = true;
2812 break;
2813 }
2814 }
2815 }
2816 if (u.signature.return_type) {
2817 Error_Context cntxt(u.signature.return_type, "In return type");
2818 u.signature.return_type->set_genname(get_genname_own(), string('0'));
2819 u.signature.return_type->set_parent_type(this);
2820 u.signature.return_type->chk();
2821 u.signature.return_type->chk_embedded(false,
2822 "the return type of a signature");
2823 if (!u.signature.component_internal &&
2824 u.signature.return_type->is_component_internal())
2825 u.signature.component_internal = true;
2826 }
2827 if (u.signature.exceptions) {
2828 u.signature.exceptions->chk(this);
2829 if (!u.signature.component_internal) {
2830 size_t nof_types = u.signature.exceptions->get_nof_types();
2831 for (size_t i=0; i<nof_types; i++) {
2832 if (u.signature.exceptions->get_type_byIndex(i)->
2833 is_component_internal()) {
2834 u.signature.component_internal = true;
2835 break;
2836 }
2837 }
2838 }
2839 }
2840 }
2841
2842 void Type::chk_Fat()
2843 {
2844 if(checked) return;
2845 checked = true;
2846 Scope *parlist_scope = my_scope;
2847 // the runs on clause must be checked before the formal parameter list
2848 // in order to determine the right scope
2849 if (u.fatref.runs_on.ref) {
2850 if (typetype == T_FUNCTION) u.fatref.is_startable = true;
2851 Error_Context cntxt2(u.fatref.runs_on.ref, "In `runs on' clause");
2852 u.fatref.runs_on.type = u.fatref.runs_on.ref->chk_comptype_ref();
2853 if(u.fatref.runs_on.type) {
2854 Ttcn::Module *my_module =
2855 dynamic_cast<Ttcn::Module*>(my_scope->get_scope_mod());
2856 if (!my_module) FATAL_ERROR("Type::chk_Fat()");
2857 parlist_scope = my_module->get_runs_on_scope(u.fatref.runs_on.type);
2858 }
2859 }
2860 u.fatref.fp_list->set_my_scope(parlist_scope);
2861 switch (typetype) {
2862 case T_FUNCTION:
2863 u.fatref.fp_list->chk(Ttcn::Definition::A_FUNCTION);
2864 u.fatref.fp_list->chk_noLazyParams();
2865 if (u.fatref.is_startable && !u.fatref.fp_list->get_startability())
2866 u.fatref.is_startable = false;
2867 if (u.fatref.return_type) {
2868 Error_Context cntxt2(u.fatref.return_type, "In return type");
2869 u.fatref.return_type->chk();
2870 u.fatref.return_type->chk_as_return_type(!u.fatref.returns_template,
2871 "function type");
2872 if (u.fatref.is_startable && u.fatref.return_type->get_type_refd_last()
2873 ->get_typetype() == T_DEFAULT) u.fatref.is_startable = false;
2874
2875 }
2876 break;
2877 case T_ALTSTEP:
2878 u.fatref.fp_list->chk(Ttcn::Definition::A_ALTSTEP);
2879 u.fatref.fp_list->chk_noLazyParams();
2880 break;
2881 case T_TESTCASE:
2882 u.fatref.fp_list->chk(Ttcn::Definition::A_TESTCASE);
2883 u.fatref.fp_list->chk_noLazyParams();
2884 if (u.fatref.system.ref) {
2885 Error_Context cntxt2(u.fatref.runs_on.ref, "In `system' clause");
2886 u.fatref.system.type = u.fatref.system.ref->chk_comptype_ref();
2887 }
2888 break;
2889 default:
2890 FATAL_ERROR("Type::chk_Fat()");
2891 }
2892 if (!semantic_check_only)
2893 u.fatref.fp_list->set_genname(get_genname_own());
2894 }
2895
2896 void Type::chk_address()
2897 {
2898 Type *t = get_type_refd_last();
2899 switch (t->typetype) {
2900 case T_PORT:
2901 error("Port type `%s' cannot be the address type",
2902 t->get_typename().c_str());
2903 break;
2904 case T_COMPONENT:
2905 error("Component type `%s' cannot be the address type",
2906 t->get_typename().c_str());
2907 break;
2908 case T_SIGNATURE:
2909 error("Signature `%s' cannot be the address type",
2910 t->get_typename().c_str());
2911 break;
2912 case T_DEFAULT:
2913 error("Default type cannot be the address type");
2914 break;
2915 case T_ANYTYPE:
2916 error("TTCN-3 anytype cannot be the address type");
2917 break;
2918 default:
2919 return;
2920 }
2921 clean_up();
2922 }
2923
2924 void Type::chk_embedded(bool default_allowed, const char *error_msg)
2925 {
2926 Type *t=get_type_refd_last();
2927 switch (t->typetype) {
2928 case T_PORT:
2929 error("Port type `%s' cannot be %s", t->get_typename().c_str(),
2930 error_msg);
2931 break;
2932 case T_SIGNATURE:
2933 error("Signature `%s' cannot be %s", t->get_typename().c_str(),
2934 error_msg);
2935 break;
2936 case T_DEFAULT:
2937 if (!default_allowed) error("Default type cannot be %s", error_msg);
2938 break;
2939 default:
2940 break;
2941 }
2942 }
2943
2944 void Type::chk_recursions(ReferenceChain& refch)
2945 {
2946 if (recurs_checked) return;
2947 Type *t = this;
2948 for ( ; ; ) {
2949 if (!refch.add(t->get_fullname())) {
2950 // an error has been found (and reported by refch.add)
2951 recurs_checked = true;
2952 return;
2953 }
2954 if (!t->is_ref()) break;
2955 t = t->get_type_refd();
2956 }
2957 switch (t->typetype) {
2958 case T_SEQ_A:
2959 case T_SEQ_T:
2960 case T_SET_A:
2961 case T_SET_T:
2962 for(size_t i = 0; i < t->get_nof_comps(); i++) {
2963 CompField *cf = t->get_comp_byIndex(i);
2964 if(!cf->get_is_optional()) {
2965 refch.mark_state();
2966 cf->get_type()->chk_recursions(refch);
2967 refch.prev_state();
2968 }
2969 // an optional field can "stop" the recursion
2970 } // for i
2971 break;
2972 case T_CHOICE_A:
2973 case T_CHOICE_T: {
2974 refch.set_error_reporting(false);
2975 refch.mark_error_state();
2976 for (size_t i = 0; i < t->get_nof_comps(); ++i) {
2977 refch.mark_state();
2978 CompField* cf = t->get_comp_byIndex(i);
2979 cf->get_type()->chk_recursions(refch);
2980 refch.prev_state();
2981 }
2982
2983 if (refch.nof_errors() == t->get_nof_comps()) {
2984 refch.report_errors();
2985 }
2986
2987 refch.prev_error_state();
2988 refch.set_error_reporting(true);
2989 break;
2990 }
2991 case T_ANYTYPE:
2992 case T_OPENTYPE:
2993 if(t->get_nof_comps()==1)
2994 t->get_comp_byIndex(0)->get_type()->chk_recursions(refch);
2995 break;
2996 case T_ARRAY:
2997 t->get_ofType()->chk_recursions(refch);
2998 break;
2999 default:
3000 break;
3001 }
3002 recurs_checked = true;
3003 }
3004
3005 void Type::chk_constructor_name(const Identifier& p_id)
3006 {
3007 switch (typetype) {
3008 case T_SEQ_T:
3009 case T_SEQ_A:
3010 case T_SET_T:
3011 case T_SET_A:
3012 case T_CHOICE_T:
3013 case T_CHOICE_A:
3014 case T_OPENTYPE:
3015 // T_ANYTYPE can not have a field of type anytype, no need to check.
3016 if (has_comp_withName(p_id)) {
3017 // HL26011: a field has the same name as the typedef.
3018 // Titan can't generate valid C++ code; better report an error.
3019 get_comp_byName(p_id)->error("Field name clashes with type name");
3020 }
3021 break;
3022 default: // can't have fields
3023 break;
3024 }
3025 }
3026
3027 bool Type::chk_startability()
3028 {
3029 if(typetype != T_FUNCTION) FATAL_ERROR("Type::chk_startable()");
3030 if(!checked) chk_Fat();
3031 if(u.fatref.is_startable) return true;
3032 if (!u.fatref.runs_on.ref) error("Functions of type `%s' cannot be started "
3033 "on a parallel test component because the type does not have `runs on' "
3034 "clause", get_typename().c_str());
3035 u.fatref.fp_list->chk_startability("Functions of type",
3036 get_typename().c_str());
3037 if (u.fatref.return_type && u.fatref.return_type->is_component_internal()) {
3038 map<Type*,void> type_chain;
3039 char* err_str = mprintf("the return type or embedded in the return type "
3040 "of function type `%s' if it is started on a parallel test component",
3041 get_typename().c_str());
3042 u.fatref.return_type->chk_component_internal(type_chain, err_str);
3043 Free(err_str);
3044 }
3045 return false;
3046 }
3047
3048 void Type::chk_as_return_type(bool as_value, const char* what)
3049 {
3050 Type *t = get_type_refd_last();
3051 switch(t->get_typetype()) {
3052 case Type::T_PORT:
3053 error("Port type `%s' cannot be the return type of a %s"
3054 , t->get_fullname().c_str(), what);
3055 break;
3056 case Type::T_SIGNATURE:
3057 if(as_value) error("A value of signature `%s' cannot be the "
3058 "return type of a %s", t->get_fullname().c_str(), what);
3059 break;
3060 default:
3061 break;
3062 }
3063 }
3064
3065 void Type::chk_this_value_ref(Value *value)
3066 {
3067 switch (value->get_valuetype()) {
3068 case Value::V_UNDEF_LOWERID:
3069 switch(typetype) {
3070 case T_INT_A:
3071 if(value->is_asn1()) {
3072 chk_Int_A();
3073 if(u.namednums.nvs
3074 && u.namednums.nvs->has_nv_withName(*value->get_val_id())) {
3075 value->set_valuetype(Value::V_NAMEDINT);
3076 value->set_my_governor(this);
3077 return;
3078 }
3079 }
3080 break;
3081 case T_ENUM_A:
3082 case T_ENUM_T:
3083 if (has_ei_withName(*value->get_val_id())) {
3084 value->set_valuetype(Value::V_ENUM);
3085 value->set_my_governor(this);
3086 return;
3087 }
3088 break;
3089 case T_REFD:
3090 case T_SELTYPE:
3091 case T_REFDSPEC:
3092 case T_OCFT:
3093 get_type_refd()->chk_this_value_ref(value);
3094 return;
3095 default:
3096 break;
3097 } // switch
3098 /* default behavior: interpret as reference */
3099 value->set_valuetype(Value::V_REFD);
3100 break;
3101 default:
3102 break;
3103 }
3104 }
3105
3106 bool Type::chk_this_value(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
3107 namedbool incomplete_allowed, namedbool omit_allowed,
3108 namedbool sub_chk, namedbool implicit_omit, namedbool is_str_elem)
3109 {
3110 bool self_ref = false;
3111 chk();
3112 Value *v_last = value->get_value_refd_last(0, expected_value);
3113 if (v_last->get_valuetype() == Value::V_OMIT) {
3114 if (!omit_allowed) {
3115 value->error("`omit' value is not allowed in this context");
3116 value->set_valuetype(Value::V_ERROR);
3117 }
3118 return false;
3119 }
3120
3121 switch (value->get_valuetype()) {
3122 case Value::V_ERROR:
3123 return false;
3124 case Value::V_REFD:
3125 return chk_this_refd_value(value, lhs, expected_value, 0, is_str_elem);
3126 case Value::V_INVOKE:
3127 chk_this_invoked_value(value, lhs, expected_value);
3128 return false; // assumes no self-ref in invoke
3129 case Value::V_EXPR:
3130 if (lhs) self_ref = value->chk_expr_self_ref(lhs);
3131 // no break
3132 case Value::V_MACRO:
3133 if (value->is_unfoldable(0, expected_value)) {
3134 typetype_t tt = value->get_expr_returntype(expected_value);
3135 if (!is_compatible_tt(tt, value->is_asn1())) {
3136 value->error("Incompatible value: `%s' value was expected",
3137 get_typename().c_str());
3138 value->set_valuetype(Value::V_ERROR);
3139 }
3140 return self_ref;
3141 }
3142 break;
3143 default:
3144 break;
3145 }
3146
3147 switch(typetype) {
3148 case T_ERROR:
3149 break;
3150 case T_NULL:
3151 chk_this_value_Null(value);
3152 break;
3153 case T_BOOL:
3154 chk_this_value_Bool(value);
3155 break;
3156 case T_INT:
3157 chk_this_value_Int(value);
3158 break;
3159 case T_INT_A:
3160 chk_this_value_Int_A(value);
3161 break;
3162 case T_REAL:
3163 chk_this_value_Real(value);
3164 break;
3165 case T_ENUM_A:
3166 case T_ENUM_T:
3167 chk_this_value_Enum(value);
3168 break;
3169 case T_BSTR:
3170 chk_this_value_BStr(value);
3171 break;
3172 case T_BSTR_A:
3173 chk_this_value_BStr_A(value);
3174 break;
3175 case T_HSTR:
3176 chk_this_value_HStr(value);
3177 break;
3178 case T_OSTR:
3179 chk_this_value_OStr(value);
3180 break;
3181 case T_CSTR:
3182 case T_USTR:
3183 case T_UTF8STRING:
3184 case T_NUMERICSTRING:
3185 case T_PRINTABLESTRING:
3186 case T_TELETEXSTRING:
3187 case T_VIDEOTEXSTRING:
3188 case T_IA5STRING:
3189 case T_GRAPHICSTRING:
3190 case T_VISIBLESTRING:
3191 case T_GENERALSTRING:
3192 case T_UNIVERSALSTRING:
3193 case T_BMPSTRING:
3194 case T_UTCTIME:
3195 case T_GENERALIZEDTIME:
3196 case T_OBJECTDESCRIPTOR:
3197 chk_this_value_CStr(value);
3198 break;
3199 case T_OID:
3200 chk_this_value_OID(value);
3201 break;
3202 case T_ROID:
3203 chk_this_value_ROID(value);
3204 break;
3205 case T_ANY:
3206 chk_this_value_Any(value);
3207 break;
3208 case T_CHOICE_A:
3209 case T_CHOICE_T:
3210 case T_OPENTYPE:
3211 case T_ANYTYPE:
3212 self_ref = chk_this_value_Choice(value, lhs, expected_value, incomplete_allowed,
3213 implicit_omit);
3214 break;
3215 case T_SEQ_T:
3216 case T_SET_T:
3217 case T_SEQ_A:
3218 case T_SET_A:
3219 self_ref = chk_this_value_Se(value, lhs, expected_value, incomplete_allowed,
3220 implicit_omit);
3221 break;
3222 case T_SEQOF:
3223 case T_SETOF:
3224 self_ref = chk_this_value_SeOf(value, lhs, expected_value, incomplete_allowed,
3225 implicit_omit);
3226 break;
3227 case T_REFD:
3228 self_ref = get_type_refd()->chk_this_value(value, lhs, expected_value,
3229 incomplete_allowed, omit_allowed, NO_SUB_CHK, implicit_omit, is_str_elem);
3230 break;
3231 case T_UNRESTRICTEDSTRING:
3232 case T_OCFT:
3233 case T_EXTERNAL:
3234 case T_EMBEDDED_PDV:
3235 case T_REFDSPEC:
3236 case T_SELTYPE:
3237 case T_ADDRESS:
3238 self_ref = get_type_refd()->chk_this_value(value, lhs, expected_value,
3239 incomplete_allowed, omit_allowed, NO_SUB_CHK, NOT_IMPLICIT_OMIT, is_str_elem);
3240 break;
3241 case T_VERDICT:
3242 chk_this_value_Verdict(value);
3243 break;
3244 case T_DEFAULT:
3245 chk_this_value_Default(value);
3246 break;
3247 case T_ARRAY:
3248 self_ref = chk_this_value_Array(value, lhs, expected_value, incomplete_allowed, implicit_omit);
3249 break;
3250 case T_PORT:
3251 // Remain silent. The error has already been reported in the definition
3252 // that the value belongs to.
3253 break;
3254 case T_SIGNATURE:
3255 self_ref = chk_this_value_Signature(value, lhs, expected_value, incomplete_allowed);
3256 break;
3257 case T_COMPONENT:
3258 chk_this_value_Component(value);
3259 break;
3260 case T_FUNCTION:
3261 case T_ALTSTEP:
3262 case T_TESTCASE:
3263 chk_this_value_FAT(value);
3264 break;
3265 default:
3266 FATAL_ERROR("Type::chk_this_value()");
3267 } // switch
3268
3269 // check value against subtype
3270 if(sub_chk && (sub_type!=NULL)) sub_type->chk_this_value(value);
3271
3272 return self_ref;
3273 }
3274
3275 bool Type::chk_this_refd_value(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
3276 ReferenceChain* refch, namedbool str_elem)
3277 {
3278 Reference *ref = value->get_reference();
3279 Assignment *ass = ref->get_refd_assignment();
3280 if (!ass) {
3281 value->set_valuetype(Value::V_ERROR);
3282 return false;
3283 }
3284
3285 ass->chk();
3286 bool self_ref = (ass == lhs);
3287
3288 // Exit immediately in case of infinite recursion.
3289 if (value->get_valuetype() != Value::V_REFD) return self_ref;
3290 bool is_const = false, error_flag = false, chk_runs_on = false;
3291 Type *governor = NULL;
3292 switch (ass->get_asstype()) {
3293 case Assignment::A_ERROR:
3294 value->set_valuetype(Value::V_ERROR);
3295 return self_ref;
3296 case Assignment::A_CONST:
3297 is_const = true;
3298 break;
3299 case Assignment::A_OBJECT:
3300 case Assignment::A_OS: {
3301 Setting *setting = ref->get_refd_setting();
3302 if (!setting || setting->get_st() == Setting::S_ERROR) {
3303 value->set_valuetype(Value::V_ERROR);
3304 return self_ref;
3305 }
3306 if (setting->get_st() != Setting::S_V) {
3307 ref->error("This InformationFromObjects construct does not refer to "
3308 "a value: `%s'", value->get_fullname().c_str());
3309 value->set_valuetype(Value::V_ERROR);
3310 return self_ref;
3311 }
3312 governor = dynamic_cast<Value*>(setting)->get_my_governor();
3313 if (!governor) FATAL_ERROR("Type::chk_this_refd_value()");
3314 is_const = true;
3315 break; }
3316 case Assignment::A_MODULEPAR:
3317 #ifdef MINGW
3318 break;
3319 #endif
3320 case Assignment::A_EXT_CONST:
3321 if (expected_value == EXPECTED_CONSTANT) {
3322 value->error("Reference to an (evaluable) constant value was "
3323 "expected instead of %s",
3324 ass->get_description().c_str());
3325 error_flag = true;
3326 }
3327 break;
3328 case Assignment::A_VAR:
3329 case Assignment::A_PAR_VAL:
3330 case Assignment::A_PAR_VAL_IN:
3331 case Assignment::A_PAR_VAL_OUT:
3332 case Assignment::A_PAR_VAL_INOUT:
3333 switch (expected_value) {
3334 case EXPECTED_CONSTANT:
3335 value->error("Reference to a constant value was expected instead of "
3336 "%s", ass->get_description().c_str());
3337 error_flag = true;
3338 break;
3339 case EXPECTED_STATIC_VALUE:
3340 value->error("Reference to a static value was expected instead of %s",
3341 ass->get_description().c_str());
3342 error_flag = true;
3343 break;
3344 default:
3345 break;
3346 }
3347 break;
3348 case Assignment::A_MODULEPAR_TEMP:
3349 case Assignment::A_TEMPLATE:
3350 case Assignment::A_VAR_TEMPLATE:
3351 case Assignment::A_PAR_TEMPL_IN:
3352 case Assignment::A_PAR_TEMPL_OUT:
3353 case Assignment::A_PAR_TEMPL_INOUT:
3354 if (expected_value != EXPECTED_TEMPLATE) {
3355 value->error("Reference to a value was expected instead of %s",
3356 ass->get_description().c_str());
3357 error_flag = true;
3358 }
3359 break;
3360 case Assignment::A_FUNCTION_RVAL:
3361 chk_runs_on = true;
3362 // No break
3363 case Assignment::A_EXT_FUNCTION_RVAL:
3364 switch (expected_value) {
3365 case EXPECTED_CONSTANT:
3366 value->error("Reference to a constant value was expected instead of "
3367 "the return value of %s",
3368 ass->get_description().c_str());
3369 error_flag = true;
3370 break;
3371 case EXPECTED_STATIC_VALUE:
3372 value->error("Reference to a static value was expected instead of "
3373 "the return value of %s",
3374 ass->get_description().c_str());
3375 error_flag = true;
3376 break;
3377 default:
3378 break;
3379 }
3380 break;
3381 case Assignment::A_FUNCTION_RTEMP:
3382 chk_runs_on = true;
3383 // No break
3384 case Assignment::A_EXT_FUNCTION_RTEMP:
3385 if (expected_value != EXPECTED_TEMPLATE) {
3386 value->error("Reference to a value was expected instead of a call of "
3387 "%s, which returns a template",
3388 ass->get_description().c_str());
3389 error_flag = true;
3390 }
3391 break;
3392 case Assignment::A_FUNCTION:
3393 case Assignment::A_EXT_FUNCTION:
3394 value->error("Reference to a %s was expected instead of a call of %s, "
3395 "which does not have return type",
3396 expected_value == EXPECTED_TEMPLATE
3397 ? "value or template" : "value",
3398 ass->get_description().c_str());
3399 value->set_valuetype(Value::V_ERROR);
3400 return self_ref;
3401 default:
3402 value->error("Reference to a %s was expected instead of %s",
3403 expected_value == EXPECTED_TEMPLATE
3404 ? "value or template" : "value",
3405 ass->get_description().c_str());
3406 value->set_valuetype(Value::V_ERROR);
3407 return self_ref;
3408 } // switch ass->get_asstype()
3409 if (chk_runs_on)
3410 ref->get_my_scope()->chk_runs_on_clause(ass, *ref, "call");
3411 if (!governor)
3412 governor = ass->get_Type()->get_field_type(ref->get_subrefs(),
3413 expected_value);
3414 if (!governor) {
3415 value->set_valuetype(Value::V_ERROR);
3416 return self_ref;
3417 }
3418 TypeCompatInfo info(value->get_my_scope()->get_scope_mod(), this,
3419 governor, true, false);
3420 info.set_str1_elem(str_elem);
3421 if (ref->get_subrefs()) info.set_str2_elem(ref->get_subrefs()->refers_to_string_element());
3422 TypeChain l_chain;
3423 TypeChain r_chain;
3424 if (!is_compatible(governor, &info, &l_chain, &r_chain)) {
3425 // Port or signature values do not exist at all. These errors are
3426 // already reported at those definitions. Extra errors should not be
3427 // reported here.
3428 Type *t = get_type_refd_last();
3429 switch (t->typetype) {
3430 case T_PORT:
3431 // Neither port values nor templates exist.
3432 break;
3433 case T_SIGNATURE:
3434 // Only signature templates may exist.
3435 if (expected_value == EXPECTED_TEMPLATE)
3436 value->error("Type mismatch: a signature template of type `%s' was "
3437 "expected instead of `%s'", get_typename().c_str(),
3438 governor->get_typename().c_str());
3439 break;
3440 default:
3441 if (info.is_subtype_error()) {
3442 value->error("%s", info.get_subtype_error().c_str());
3443 } else if (!info.is_erroneous()) {
3444 value->error("Type mismatch: a %s of type `%s' was expected "
3445 "instead of `%s'", expected_value == EXPECTED_TEMPLATE
3446 ? "value or template" : "value",
3447 get_typename().c_str(),
3448 governor->get_typename().c_str());
3449 } else {
3450 // The semantic error was found by the new code. It was better to
3451 // do the assembly inside TypeCompatInfo.
3452 value->error("%s", info.get_error_str_str().c_str());
3453 }
3454 break;
3455 }
3456 error_flag = true;
3457 } else {
3458 if (info.needs_conversion()) value->set_needs_conversion();
3459 }
3460
3461 if (error_flag) {
3462 value->set_valuetype(Value::V_ERROR);
3463 return self_ref;
3464 }
3465 // Checking for circular references.
3466 Value *v_last = value->get_value_refd_last(refch, expected_value);
3467 if (is_const && v_last->get_valuetype() != Value::V_ERROR) {
3468 // If a referenced universal charstring value points to a literal
3469 // charstring then drop the reference and create a literal ustring to
3470 // avoid run-time conversion.
3471 if (v_last->get_valuetype() == Value::V_CSTR
3472 && get_typetype_ttcn3(get_type_refd_last()->typetype) == T_USTR)
3473 value->set_valuetype(Value::V_USTR);
3474 // Check v_last against the subtype constraints.
3475 if (sub_type!=NULL) sub_type->chk_this_value(value);
3476 }
3477
3478 return self_ref;
3479 }
3480
3481 void Type::chk_this_invoked_value(Value *value, Common::Assignment *,
3482 expected_value_t expected_value)
3483 {
3484 value->get_value_refd_last(NULL, expected_value);
3485 if (value->get_valuetype() == Value::V_ERROR) return;
3486 Type *invoked_t = value->get_invoked_type(expected_value);
3487 if (invoked_t->get_typetype() == T_ERROR) return;
3488 invoked_t = invoked_t->get_type_refd_last();
3489 Type *t = 0;
3490 switch (invoked_t->get_typetype()) {
3491 case Type::T_FUNCTION:
3492 t = invoked_t->get_function_return_type();
3493 break;
3494 default:
3495 FATAL_ERROR("Type::chk_this_invoked_value()");
3496 break;
3497 }
3498 if (!t)
3499 value->error("The type `%s' has no return type, `%s' expected",
3500 invoked_t->get_typename().c_str(), get_typename().c_str());
3501 else if (!is_compatible(t, NULL)) {
3502 value->error("Incompatible value: `%s' value was expected",
3503 get_typename().c_str());
3504 }
3505 }
3506
3507 void Type::chk_this_value_Null(Value *value)
3508 {
3509 Value *v=value->get_value_refd_last();
3510 switch(v->get_valuetype()) {
3511 case Value::V_NULL:
3512 break;
3513 default:
3514 value->error("NULL value was expected");
3515 value->set_valuetype(Value::V_ERROR);
3516 break;
3517 }
3518 }
3519
3520 void Type::chk_this_value_Bool(Value *value)
3521 {
3522 Value *v=value->get_value_refd_last();
3523 switch(v->get_valuetype()) {
3524 case Value::V_BOOL:
3525 break;
3526 default:
3527 value->error("%s value was expected",
3528 value->is_asn1() ? "BOOLEAN" : "boolean");
3529 value->set_valuetype(Value::V_ERROR);
3530 break;
3531 }
3532 }
3533
3534 void Type::chk_this_value_Int(Value *value)
3535 {
3536 Value *v=value->get_value_refd_last();
3537 switch(v->get_valuetype()) {
3538 case Value::V_INT:
3539 break;
3540 default:
3541 value->error("integer value was expected");
3542 value->set_valuetype(Value::V_ERROR);
3543 break;
3544 }
3545 return;
3546 }
3547
3548 void Type::chk_this_value_Int_A(Value *value)
3549 {
3550 Value *v=value->get_value_refd_last();
3551 switch(v->get_valuetype()) {
3552 case Value::V_INT:
3553 break;
3554 case Value::V_NAMEDINT:
3555 if(!u.namednums.nvs)
3556 FATAL_ERROR("Type::chk_this_value_Int_A()");
3557 v->set_valuetype
3558 (Value::V_INT, u.namednums.nvs->
3559 get_nv_byName(*v->get_val_id())->get_value()->get_val_Int()->get_val());
3560 break;
3561 default:
3562 value->error("INTEGER value was expected");
3563 value->set_valuetype(Value::V_ERROR);
3564 break;
3565 }
3566 }
3567
3568 void Type::chk_this_value_Real(Value *value)
3569 {
3570 Value *v = value->get_value_refd_last();
3571 if (value->is_asn1()) {
3572 if (value->is_ref()) {
3573 Type *t = v->get_my_governor()->get_type_refd_last();
3574 if (t->get_typetype() != T_REAL) {
3575 value->error("REAL value was expected");
3576 value->set_valuetype(Value::V_ERROR);
3577 return;
3578 }
3579 }
3580 switch (v->get_valuetype()) {
3581 case Value::V_REAL:
3582 break;
3583 case Value::V_UNDEF_BLOCK:{
3584 v->set_valuetype(Value::V_SEQ);
3585 Identifier t_id(Identifier::ID_ASN, string("REAL"));
3586 bool self_ref = get_my_scope()->get_scope_asss()->get_local_ass_byId(t_id)
3587 ->get_Type()->chk_this_value(v, 0, EXPECTED_CONSTANT, INCOMPLETE_NOT_ALLOWED,
3588 OMIT_NOT_ALLOWED, SUB_CHK);
3589 (void)self_ref;
3590 v->set_valuetype(Value::V_REAL);
3591 break;}
3592 case Value::V_INT:
3593 v->set_valuetype(Value::V_REAL);
3594 break;
3595 default:
3596 value->error("REAL value was expected");
3597 value->set_valuetype(Value::V_ERROR);
3598 break;
3599 }
3600 } else {
3601 switch(v->get_valuetype()) {
3602 case Value::V_REAL:
3603 break;
3604 default:
3605 value->error("float value was expected");
3606 value->set_valuetype(Value::V_ERROR);
3607 break;
3608 }
3609 }
3610 }
3611
3612 void Type::chk_this_value_Enum(Value *value)
3613 {
3614 switch(value->get_valuetype()) {
3615 case Value::V_ENUM:
3616 break;
3617 default:
3618 value->error("%s value was expected",
3619 value->is_asn1() ? "ENUMERATED" : "enumerated");
3620 value->set_valuetype(Value::V_ERROR);
3621 break;
3622 }
3623 }
3624
3625 void Type::chk_this_value_BStr(Value *value)
3626 {
3627 Value *v = value->get_value_refd_last();
3628 switch(v->get_valuetype()) {
3629 case Value::V_BSTR:
3630 break;
3631 default:
3632 value->error("bitstring value was expected");
3633 value->set_valuetype(Value::V_ERROR);
3634 break;
3635 }
3636 }
3637
3638 void Type::chk_this_value_namedbits(Value *value)
3639 {
3640 if (!value) FATAL_ERROR("Type::chk_this_value_namedbits()");
3641 value->set_valuetype(Value::V_NAMEDBITS);
3642 if(!u.namednums.nvs) {
3643 value->error("No named bits are defined in type `%s'",
3644 get_typename().c_str());
3645 value->set_valuetype(Value::V_ERROR);
3646 return;
3647 }
3648 string *bstring = new string("");
3649 for(size_t i=0; i < value->get_nof_ids(); i++) {
3650 Identifier *id = value->get_id_byIndex(i);
3651 if(!u.namednums.nvs->has_nv_withName(*id)) {
3652 delete bstring;
3653 error("No named bit with name `%s' is defined in type `%s'",
3654 id->get_dispname().c_str(), get_typename().c_str());
3655 value->set_valuetype(Value::V_ERROR);
3656 return;
3657 }
3658 size_t bitnum = static_cast<size_t>
3659 (u.namednums.nvs->get_nv_byName(*id)->get_value()->get_val_Int()
3660 ->get_val());
3661 if(bstring->size() < bitnum + 1) bstring->resize(bitnum + 1, '0');
3662 (*bstring)[bitnum] = '1';
3663 }
3664 value->set_valuetype(Value::V_BSTR, bstring);
3665 }
3666
3667 void Type::chk_this_value_BStr_A(Value *value)
3668 {
3669 Value *v = value->get_value_refd_last();
3670 if (value->is_asn1()) {
3671 if(value->is_ref()) {
3672 Type *t = v->get_my_governor()->get_type_refd_last();
3673 if(t->get_typetype()!=T_BSTR_A && t->get_typetype()!=T_BSTR) {
3674 value->error("(reference to) BIT STRING value was expected");
3675 value->set_valuetype(Value::V_ERROR);
3676 return;
3677 }
3678 }
3679 switch(v->get_valuetype()) {
3680 case Value::V_BSTR:
3681 break;
3682 case Value::V_HSTR:
3683 if (v != value) FATAL_ERROR("Common::Type::chk_this_value_BStr_A()");
3684 v->set_valuetype(Value::V_BSTR);
3685 break;
3686 case Value::V_UNDEF_BLOCK:
3687 if (v != value) FATAL_ERROR("Type::chk_this_value_BStr_A()");
3688 chk_this_value_namedbits(v);
3689 break;
3690 default:
3691 value->error("BIT STRING value was expected");
3692 value->set_valuetype(Value::V_ERROR);
3693 return;
3694 }
3695 } else {
3696 switch(v->get_valuetype()) {
3697 case Value::V_BSTR:
3698 break;
3699 default:
3700 value->error("bitstring value was expected");
3701 value->set_valuetype(Value::V_ERROR);
3702 break;
3703 }
3704 }
3705 }
3706
3707 void Type::chk_this_value_HStr(Value *value)
3708 {
3709 Value *v = value->get_value_refd_last();
3710 switch (v->get_valuetype()) {
3711 case Value::V_HSTR:
3712 break;
3713 default:
3714 value->error("hexstring value was expected");
3715 value->set_valuetype(Value::V_ERROR);
3716 break;
3717 }
3718 }
3719
3720 void Type::chk_this_value_OStr(Value *value)
3721 {
3722 Value *v = value->get_value_refd_last();
3723 if (value->is_asn1()) {
3724 if (value->is_ref()) {
3725 Type *t = v->get_my_governor()->get_type_refd_last();
3726 if(t->get_typetype() != T_OSTR) {
3727 value->error("(reference to) OCTET STRING value was expected");
3728 value->set_valuetype(Value::V_ERROR);
3729 return;
3730 }
3731 }
3732 switch(v->get_valuetype()) {
3733 case Value::V_OSTR:
3734 break;
3735 case Value::V_BSTR:
3736 case Value::V_HSTR:
3737 if (v != value) FATAL_ERROR("Type::chk_this_value_OStr()");
3738 v->set_valuetype(Value::V_OSTR);
3739 break;
3740 default:
3741 value->error("OCTET STRING value was expected");
3742 value->set_valuetype(Value::V_ERROR);
3743 break;
3744 }
3745 } else {
3746 switch(v->get_valuetype()) {
3747 case Value::V_OSTR:
3748 break;
3749 default:
3750 value->error("octetstring value was expected");
3751 value->set_valuetype(Value::V_ERROR);
3752 break;
3753 }
3754 }
3755 }
3756
3757 /** \todo enhance */
3758 void Type::chk_this_value_CStr(Value *value)
3759 {
3760
3761 switch(value->get_valuetype()) {
3762 case Value::V_UNDEF_BLOCK:
3763 value->set_valuetype(Value::V_CHARSYMS);
3764 if (value->get_valuetype() == Value::V_ERROR) return;
3765 // no break
3766 case Value::V_CHARSYMS:
3767 switch (typetype) {
3768 case T_USTR:
3769 case T_UTF8STRING:
3770 case T_BMPSTRING:
3771 case T_UNIVERSALSTRING:
3772 value->set_valuetype(Value::V_USTR);
3773 break;
3774 case T_TELETEXSTRING:
3775 case T_VIDEOTEXSTRING:
3776 case T_GRAPHICSTRING:
3777 case T_OBJECTDESCRIPTOR:
3778 case T_GENERALSTRING:
3779 value->set_valuetype(Value::V_ISO2022STR);
3780 break;
3781 case T_CSTR:
3782 case T_NUMERICSTRING:
3783 case T_PRINTABLESTRING:
3784 case T_IA5STRING:
3785 case T_VISIBLESTRING:
3786 case T_UTCTIME:
3787 case T_GENERALIZEDTIME:
3788 value->set_valuetype(Value::V_CSTR);
3789 break;
3790 default:
3791 FATAL_ERROR("chk_this_value_CStr()");
3792 } // switch
3793 break;
3794 case Value::V_USTR:
3795 switch (typetype) {
3796 case T_USTR:
3797 case T_UTF8STRING:
3798 case T_BMPSTRING:
3799 case T_UNIVERSALSTRING:
3800 break;
3801 case T_TELETEXSTRING:
3802 case T_VIDEOTEXSTRING:
3803 case T_GRAPHICSTRING:
3804 case T_OBJECTDESCRIPTOR:
3805 case T_GENERALSTRING:
3806 // accept it
3807 /*
3808 if(value->get_val_ustr().is_cstr()) {
3809 value->warning("ISO-2022 string value was expected (converting"
3810 " simple ISO-10646 string).");
3811 value->set_valuetype(Value::V_CSTR);
3812 }
3813 else {
3814 value->error("ISO-2022 string value was expected (instead of"
3815 " ISO-10646 string).");
3816 value->set_valuetype(Value::V_ERROR);
3817 }
3818 */
3819 break;
3820 case T_CSTR:
3821 case T_NUMERICSTRING:
3822 case T_PRINTABLESTRING:
3823 case T_IA5STRING:
3824 case T_VISIBLESTRING:
3825 case T_UTCTIME:
3826 case T_GENERALIZEDTIME:
3827 value->set_valuetype(Value::V_CSTR);
3828 break;
3829 default:
3830 FATAL_ERROR("Type::chk_this_value_CStr()");
3831 } // switch
3832 break;
3833 case Value::V_CSTR:
3834 switch (typetype) {
3835 case T_USTR:
3836 case T_UTF8STRING:
3837 case T_BMPSTRING:
3838 case T_UNIVERSALSTRING:
3839 value->set_valuetype(Value::V_USTR);
3840 break;
3841 case T_TELETEXSTRING:
3842 case T_VIDEOTEXSTRING:
3843 case T_GRAPHICSTRING:
3844 case T_OBJECTDESCRIPTOR:
3845 case T_GENERALSTRING:
3846 value->set_valuetype(Value::V_ISO2022STR);
3847 break;
3848 case T_CSTR:
3849 case T_NUMERICSTRING:
3850 case T_PRINTABLESTRING:
3851 case T_IA5STRING:
3852 case T_VISIBLESTRING:
3853 case T_UTCTIME:
3854 case T_GENERALIZEDTIME:
3855 break;
3856 default:
3857 FATAL_ERROR("chk_this_value_CStr()");
3858 } // switch
3859 break;
3860 case Value::V_ISO2022STR:
3861 switch (typetype) {
3862 case T_USTR:
3863 case T_UTF8STRING:
3864 case T_BMPSTRING:
3865 case T_UNIVERSALSTRING:
3866 value->error("ISO-10646 string value was expected (instead of"
3867 " ISO-2022 string).");
3868 value->set_valuetype(Value::V_ERROR);
3869 break;
3870 case T_TELETEXSTRING:
3871 case T_VIDEOTEXSTRING:
3872 case T_GRAPHICSTRING:
3873 case T_OBJECTDESCRIPTOR:
3874 case T_GENERALSTRING:
3875 break;
3876 case T_CSTR:
3877 case T_NUMERICSTRING:
3878 case T_PRINTABLESTRING:
3879 case T_IA5STRING:
3880 case T_VISIBLESTRING:
3881 case T_UTCTIME:
3882 case T_GENERALIZEDTIME:
3883 value->set_valuetype(Value::V_ISO2022STR);
3884 break;
3885 default:
3886 FATAL_ERROR("chk_this_value_CStr()");
3887 } // switch
3888 break;
3889 default:
3890 value->error("character string value was expected");
3891 value->set_valuetype(Value::V_ERROR);
3892 break;
3893 }
3894 }
3895
3896 void Type::chk_this_value_OID(Value *value)
3897 {
3898 Value *v = value->get_value_refd_last();
3899 if (value->is_asn1()) {
3900 if (value->is_ref()) {
3901 Type *t = v->get_my_governor()->get_type_refd_last();
3902 if (t->get_typetype() != T_OID) {
3903 value->error("(reference to) OBJECT IDENTIFIER value was "
3904 "expected");
3905 value->set_valuetype(Value::V_ERROR);
3906 return;
3907 }
3908 }
3909 switch (v->get_valuetype()) {
3910 case Value::V_OID:
3911 break;
3912 case Value::V_UNDEF_BLOCK:
3913 if (v != value) FATAL_ERROR("Type::chk_this_value_OID()");
3914 v->set_valuetype(Value::V_OID);
3915 v->chk();
3916 break;
3917 default:
3918 value->error("OBJECT IDENTIFIER value was expected");
3919 value->set_valuetype(Value::V_ERROR);
3920 break;
3921 }
3922 } else {
3923 switch (v->get_valuetype()) {
3924 case Value::V_OID:
3925 v->chk();
3926 break;
3927 default:
3928 value->error("objid value was expected");
3929 value->set_valuetype(Value::V_ERROR);
3930 break;
3931 }
3932 }
3933 }
3934
3935 void Type::chk_this_value_ROID(Value *value)
3936 {
3937 Value *v = value->get_value_refd_last();
3938 if(value->is_ref()) {
3939 Type *t = v->get_my_governor()->get_type_refd_last();
3940 if (t->get_typetype() != T_ROID) {
3941 value->error("(reference to) RELATIVE-OID value was expected");
3942 value->set_valuetype(Value::V_ERROR);
3943 return;
3944 }
3945 }
3946 switch(v->get_valuetype()) {
3947 case Value::V_ROID:
3948 break;
3949 case Value::V_UNDEF_BLOCK:
3950 if (v != value) FATAL_ERROR("Type::chk_this_value_ROID()");
3951 v->set_valuetype(Value::V_ROID);
3952 v->chk();
3953 break;
3954 default:
3955 value->error("RELATIVE-OID value was expected");
3956 value->set_valuetype(Value::V_ERROR);
3957 break;
3958 }
3959 }
3960
3961 void Type::chk_this_value_Any(Value *value)
3962 {
3963 Value *v = value->get_value_refd_last();
3964 if (value->is_asn1()) {
3965 if (value->is_ref()) {
3966 Type *t = v->get_my_governor()->get_type_refd_last();
3967 if(t->get_typetype()!=T_ANY && t->get_typetype()!=T_OSTR) {
3968 value->error("(reference to) OCTET STRING or ANY type value"
3969 " was expected");
3970 value->set_valuetype(Value::V_ERROR);
3971 return;
3972 }
3973 }
3974 switch(v->get_valuetype()) {
3975 case Value::V_OSTR:
3976 break;
3977 case Value::V_HSTR:
3978 if (v!=value) FATAL_ERROR("Type::chk_this_value_Any()");
3979 v->set_valuetype(Value::V_OSTR);
3980 break;
3981 default:
3982 value->error("ANY (OCTET STRING) value was expected");
3983 value->set_valuetype(Value::V_ERROR);
3984 break;
3985 }
3986 }
3987 else { // is ttcn
3988 switch(v->get_valuetype()) {
3989 case Value::V_OSTR:
3990 break;
3991 default:
3992 value->error("octetstring value was expected for ASN ANY type");
3993 value->set_valuetype(Value::V_ERROR);
3994 break;
3995 }
3996 }
3997 }
3998
3999 /** Return a string containing the names of existing fields (components).
4000 *
4001 * @param t a Type object
4002 * @return a string (l-value, temporary)
4003 * @pre t must be a sequence, choice, set, anytype, open type
4004 */
4005 static string actual_fields(Type& t) // alas, not even get_nof_comps() is const
4006 {
4007 static const string has_no(" has no ");
4008 size_t ncomps = t.get_nof_comps();
4009 const string fields_or_comps(t.is_asn1() ? "components" : "fields");
4010 if (ncomps) {
4011 string msg("Valid ");
4012 msg += fields_or_comps;
4013 msg += ": ";
4014 msg += t.get_comp_byIndex(0)->get_name().get_dispname();
4015 for (size_t ci=1; ci < ncomps; ++ci) {
4016 msg += ',';
4017 msg += t.get_comp_byIndex(ci)->get_name().get_dispname();
4018 }
4019 return msg;
4020 }
4021 else return t.get_fullname() + has_no + fields_or_comps;
4022 }
4023
4024
4025 bool Type::chk_this_value_Choice(Value *value, Common::Assignment *lhs,
4026 expected_value_t expected_value, namedbool incomplete_allowed, namedbool implicit_omit)
4027 {
4028 bool self_ref = false;
4029 switch(value->get_valuetype()) {
4030 case Value::V_SEQ:
4031 if (value->is_asn1()) {
4032 value->error("CHOICE value was expected for type `%s'",
4033 get_fullname().c_str());
4034 value->set_valuetype(Value::V_ERROR);
4035 break;
4036 } else {
4037 // the valuetype can be ERROR if the value has no fields at all
4038 if (value->get_valuetype() == Value::V_ERROR) return false;
4039 // The value notation for TTCN record/union types
4040 // cannot be distinguished during parsing. Now we know it's a union.
4041 value->set_valuetype(Value::V_CHOICE);
4042 }
4043 // no break
4044 case Value::V_CHOICE: {
4045 if (!value->is_asn1() && typetype == T_OPENTYPE) {
4046 // allow the alternatives of open types as both lower and upper identifiers
4047 value->set_alt_name_to_lowercase();
4048 }
4049 const Identifier& alt_name = value->get_alt_name();
4050 if(!has_comp_withName(alt_name)) {
4051 if (value->is_asn1()) {
4052 value->error("Reference to non-existent alternative `%s' in CHOICE"
4053 " value for type `%s'",
4054 alt_name.get_dispname().c_str(),
4055 get_fullname().c_str());
4056 } else {
4057 value->error("Reference to non-existent field `%s' in union "
4058 "value for type `%s'",
4059 alt_name.get_dispname().c_str(),
4060 get_fullname().c_str());
4061 }
4062 value->set_valuetype(Value::V_ERROR);
4063 value->note("%s", actual_fields(*this).c_str());
4064 return self_ref;
4065 }
4066 Type *alt_type = get_comp_byName(alt_name)->get_type();
4067 Value *alt_value = value->get_alt_value();
4068 Error_Context cntxt(value, "In value for %s `%s'",
4069 value->is_asn1() ? "alternative" : "union field",
4070 alt_name.get_dispname().c_str());
4071 alt_value->set_my_governor(alt_type);
4072 alt_type->chk_this_value_ref(alt_value);
4073 self_ref |= alt_type->chk_this_value(alt_value, lhs, expected_value,
4074 incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
4075 if (alt_value->get_valuetype() == Value::V_NOTUSED) {
4076 value->set_valuetype(Value::V_NOTUSED);
4077 }
4078 break;}
4079 default:
4080 value->error("%s value was expected for type `%s'",
4081 value->is_asn1() ? "CHOICE" : "union",
4082 get_fullname().c_str());
4083 value->set_valuetype(Value::V_ERROR);
4084 break;
4085 }
4086 return self_ref;
4087 }
4088
4089 bool Type::chk_this_value_Se(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4090 namedbool incomplete_allowed, namedbool implicit_omit)
4091 {
4092 if (value->is_asn1())
4093 return chk_this_value_Se_A(value, lhs, expected_value, implicit_omit);
4094 else
4095 return chk_this_value_Se_T(value, lhs, expected_value, incomplete_allowed,
4096 implicit_omit);
4097 }
4098
4099 bool Type::chk_this_value_Se_T(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4100 namedbool incomplete_allowed, namedbool implicit_omit)
4101 {
4102 switch (value->get_valuetype()) {
4103 case Value::V_SEQ:
4104 if (typetype == T_SET_A || typetype == T_SET_T) {
4105 value->set_valuetype(Value::V_SET);
4106 return chk_this_value_Set_T(value, lhs, expected_value, incomplete_allowed,
4107 implicit_omit);
4108 } else {
4109 return chk_this_value_Seq_T(value, lhs, expected_value, incomplete_allowed,
4110 implicit_omit);
4111 }
4112 break;
4113 case Value::V_SEQOF:
4114 if (typetype == T_SET_A || typetype == T_SET_T) {
4115 if (value->get_nof_comps() == 0) {
4116 if (get_nof_comps() == 0) {
4117 value->set_valuetype(Value::V_SET);
4118 } else {
4119 value->error("A non-empty set value was expected for type `%s'",
4120 get_fullname().c_str());
4121 value->set_valuetype(Value::V_ERROR);
4122 }
4123 } else {
4124 // This will catch the indexed assignment notation as well.
4125 value->error("Value list notation cannot be used for "
4126 "%s type `%s'", typetype == T_SET_A ? "SET" : "set",
4127 get_fullname().c_str());
4128 value->set_valuetype(Value::V_ERROR);
4129 }
4130 } else {
4131 if (value->is_indexed()) {
4132 value->error("Indexed assignment notation cannot be used for %s "
4133 "type `%s'", typetype == T_SEQ_A
4134 ? "SEQUENCE" : "record",
4135 get_fullname().c_str());
4136 value->set_valuetype(Value::V_ERROR);
4137 } else {
4138 value->set_valuetype(Value::V_SEQ);
4139 return chk_this_value_Seq_T(value, lhs, expected_value, incomplete_allowed,
4140 implicit_omit);
4141 }
4142 }
4143 break;
4144 default:
4145 value->error("%s value was expected for type `%s'",
4146 typetype == T_SEQ_T ? "Record" : "Set",
4147 get_fullname().c_str());
4148 value->set_valuetype(Value::V_ERROR);
4149 break;
4150 }
4151 return false;
4152 }
4153
4154 bool Type::chk_this_value_Seq_T(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4155 namedbool incomplete_allowed, namedbool implicit_omit)
4156 {
4157 bool self_ref = false;
4158 map<string, NamedValue> comp_map;
4159 // it is set to false if we have lost the ordering
4160 bool in_synch = true;
4161 const size_t n_type_comps = get_nof_comps();
4162 size_t n_value_comps = value->get_nof_comps();
4163 // for incomplete values
4164 CompField *last_cf = 0;
4165 size_t next_index = 0;
4166 size_t seq_index = 0;
4167 bool is_empty = n_type_comps > 0; // don't do this check if the record type has no fields
4168 for (size_t v_i = 0; v_i < n_value_comps; v_i++, seq_index++) {
4169 NamedValue *nv = value->get_se_comp_byIndex(v_i);
4170 const Identifier& value_id = nv->get_name();
4171 const string& value_name = value_id.get_name();
4172 const char *value_dispname_str = value_id.get_dispname().c_str();
4173 if (!has_comp_withName(value_id)) {
4174 nv->error("Reference to non-existent field `%s' in record value for "
4175 "type `%s'", value_dispname_str, get_typename().c_str());
4176 nv->note("%s", actual_fields(*this).c_str());
4177 in_synch = false;
4178 continue;
4179 } else if (comp_map.has_key(value_name)) {
4180 nv->error("Duplicate record field `%s'", value_dispname_str);
4181 comp_map[value_name]->note("Field `%s' is already given here",
4182 value_dispname_str);
4183 in_synch = false;
4184 } else comp_map.add(value_name, nv);
4185 CompField *cf = get_comp_byName(value_id);
4186 // check the ordering of fields
4187 if (in_synch) {
4188 if (incomplete_allowed) {
4189 bool found = false;
4190 for (size_t i = next_index; i < n_type_comps; i++) {
4191 CompField *cf2 = get_comp_byIndex(i);
4192 if (value_name == cf2->get_name().get_name()) {
4193 last_cf = cf2;
4194 next_index = i + 1;
4195 found = true;
4196 break;
4197 }
4198 }
4199 if (!found) {
4200 nv->error("Field `%s' cannot appear after field `%s' in record "
4201 "value", value_dispname_str,
4202 last_cf->get_name().get_dispname().c_str());
4203 in_synch = false;
4204 }
4205 } else {
4206 // the value must be complete unless implicit omit is set
4207 CompField *cf2 = get_comp_byIndex(seq_index);
4208 CompField *cf2_orig = cf2;
4209 while (implicit_omit && seq_index < n_type_comps && cf2 != cf &&
4210 cf2->get_is_optional())
4211 cf2 = get_comp_byIndex(++seq_index);
4212 if (seq_index >= n_type_comps || cf2 != cf) {
4213 nv->error("Unexpected field `%s' in record value, "
4214 "expecting `%s'", value_dispname_str,
4215 cf2_orig->get_name().get_dispname().c_str());
4216 in_synch = false;
4217 }
4218 }
4219 }
4220 Type *type = cf->get_type();
4221 Value *comp_value = nv->get_value();
4222 comp_value->set_my_governor(type);
4223 if (comp_value->get_valuetype() == Value::V_NOTUSED) {
4224 if (implicit_omit) {
4225 comp_value->set_valuetype(Value::V_OMIT);
4226 } else {
4227 continue;
4228 }
4229 }
4230 Error_Context cntxt(nv, "In value for record field `%s'",
4231 value_dispname_str);
4232 type->chk_this_value_ref(comp_value);
4233 self_ref |= type->chk_this_value(comp_value, lhs, expected_value, incomplete_allowed,
4234 cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
4235 if (comp_value->get_valuetype() != Value::V_NOTUSED) {
4236 is_empty = false;
4237 }
4238 }
4239 if (is_empty) {
4240 // all of the record's fields are unused (-), set the record to unused
4241 // to avoid unnecessary code generation
4242 value->set_valuetype(Value::V_NOTUSED);
4243 }
4244 else if (!incomplete_allowed || implicit_omit) {
4245 for (size_t i = 0; i < n_type_comps; i++) {
4246 const Identifier& id = get_comp_byIndex(i)->get_name();
4247 if (!comp_map.has_key(id.get_name())) {
4248 if (get_comp_byIndex(i)->get_is_optional() && implicit_omit)
4249 value->add_se_comp(new NamedValue(new Identifier(id),
4250 new Value(Value::V_OMIT)));
4251 else if (!incomplete_allowed)
4252 value->error("Field `%s' is missing from record value",
4253 id.get_dispname().c_str());
4254 }
4255 }
4256 }
4257 comp_map.clear();
4258 return self_ref;
4259 }
4260
4261 bool Type::chk_this_value_Set_T(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4262 namedbool incomplete_allowed, namedbool implicit_omit)
4263 {
4264 bool self_ref = false;
4265 map<string, NamedValue> comp_map;
4266 size_t n_type_comps = get_nof_comps();
4267 size_t n_value_comps = value->get_nof_comps();
4268 bool is_empty = n_type_comps > 0; // don't do this check if the set type has no fields
4269 for(size_t v_i = 0; v_i < n_value_comps; v_i++) {
4270 NamedValue *nv = value->get_se_comp_byIndex(v_i);
4271 const Identifier& value_id = nv->get_name();
4272 const string& value_name = value_id.get_name();
4273 const char *value_dispname_str = value_id.get_dispname().c_str();
4274 if (!has_comp_withName(value_id)) {
4275 nv->error("Reference to non-existent field `%s' in set value for "
4276 "type `%s'", value_dispname_str, get_typename().c_str());
4277 nv->note("%s", actual_fields(*this).c_str());
4278 continue;
4279 } else if (comp_map.has_key(value_name)) {
4280 nv->error("Duplicate set field `%s'", value_dispname_str);
4281 comp_map[value_name]->note("Field `%s' is already given here",
4282 value_dispname_str);
4283 } else comp_map.add(value_name, nv);
4284 CompField *cf = get_comp_byName(value_id);
4285 Type *type = cf->get_type();
4286 Value *comp_value = nv->get_value();
4287 comp_value->set_my_governor(type);
4288 if (comp_value->get_valuetype() == Value::V_NOTUSED) {
4289 if (implicit_omit) {
4290 comp_value->set_valuetype(Value::V_OMIT);
4291 } else {
4292 continue;
4293 }
4294 }
4295 Error_Context cntxt(nv, "In value for set field `%s'",
4296 value_dispname_str);
4297 type->chk_this_value_ref(comp_value);
4298 self_ref |= type->chk_this_value(comp_value, lhs, expected_value, incomplete_allowed,
4299 cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
4300 if (comp_value->get_valuetype() != Value::V_NOTUSED) {
4301 is_empty = false;
4302 }
4303 }
4304 if (is_empty) {
4305 // all of the set's fields are unused (-), set the set to unused to avoid
4306 // unnecessary code generation
4307 value->set_valuetype(Value::V_NOTUSED);
4308 }
4309 else if (!incomplete_allowed || implicit_omit) {
4310 for (size_t i = 0; i < n_type_comps; i++) {
4311 const Identifier& id = get_comp_byIndex(i)->get_name();
4312 if(!comp_map.has_key(id.get_name())) {
4313 if (get_comp_byIndex(i)->get_is_optional() && implicit_omit)
4314 value->add_se_comp(new NamedValue(new Identifier(id),
4315 new Value(Value::V_OMIT)));
4316 else if (!incomplete_allowed)
4317 value->error("Field `%s' is missing from set value %s",
4318 id.get_dispname().c_str(), implicit_omit ? "yes" : "no");
4319 }
4320 }
4321 }
4322 comp_map.clear();
4323 return self_ref;
4324 }
4325
4326 bool Type::chk_this_value_Se_A(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4327 namedbool implicit_omit)
4328 {
4329 if(value->get_valuetype()==Value::V_UNDEF_BLOCK) {
4330 if(typetype == T_SEQ_A) value->set_valuetype(Value::V_SEQ);
4331 else value->set_valuetype(Value::V_SET);
4332 } // if V_UNDEF
4333 switch(value->get_valuetype()) {
4334 case Value::V_SEQ:
4335 return chk_this_value_Seq_A(value, lhs, expected_value, implicit_omit);
4336 case Value::V_SET:
4337 return chk_this_value_Set_A(value, lhs, expected_value, implicit_omit);
4338 default:
4339 value->error("%s value was expected",
4340 typetype == T_SEQ_A ? "SEQUENCE" : "SET");
4341 value->set_valuetype(Value::V_ERROR);
4342 break;
4343 }
4344 return false;
4345 }
4346
4347 bool Type::chk_this_value_Seq_A(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4348 namedbool implicit_omit)
4349 {
4350 bool self_ref = false;
4351 map<string, NamedValue> comp_map;
4352 // it is set to false if we have lost the ordering
4353 bool in_synch = true;
4354 size_t n_type_comps = u.secho.ctss->get_nof_comps();
4355 size_t n_value_comps = value->get_nof_comps();
4356 size_t t_i = 0;
4357 for (size_t v_i = 0; v_i < n_value_comps; v_i++) {
4358 NamedValue *nv = value->get_se_comp_byIndex(v_i);
4359 const Identifier& value_id = nv->get_name();
4360 const string& value_name = value_id.get_name();
4361 const char *value_dispname_str = value_id.get_dispname().c_str();
4362 if (!u.secho.ctss->has_comp_withName(value_id)) {
4363 nv->error("Reference to non-existent component `%s' of SEQUENCE "
4364 "type `%s'", value_dispname_str, get_typename().c_str());
4365 nv->note("%s", actual_fields(*this).c_str());
4366 in_synch = false;
4367 continue;
4368 } else if (comp_map.has_key(value_name)) {
4369 nv->error("Duplicate SEQUENCE component `%s'", value_dispname_str);
4370 comp_map[value_name]->note("Component `%s' is already given here",
4371 value_dispname_str);
4372 in_synch = false;
4373 } else comp_map.add(value_name, nv);
4374 CompField *cf = u.secho.ctss->get_comp_byName(value_id);
4375 if (in_synch) {
4376 CompField *cf2 = 0;
4377 for ( ; t_i < n_type_comps; t_i++) {
4378 cf2 = u.secho.ctss->get_comp_byIndex(t_i);
4379 if (cf2 == cf || (!cf2->get_is_optional() && !cf2->has_default() &&
4380 !implicit_omit))
4381 break;
4382 }
4383 if (cf2 != cf) {
4384 if (t_i < n_type_comps) {
4385 nv->error("Unexpected component `%s' in SEQUENCE value, "
4386 "expecting `%s'", value_dispname_str,
4387 cf2->get_name().get_dispname().c_str());
4388 } else {
4389 nv->error("Unexpected component `%s' in SEQUENCE value",
4390 value_dispname_str);
4391 }
4392 in_synch = false;
4393 } else t_i++;
4394 }
4395 Type *type = cf->get_type();
4396 Error_Context cntxt(nv, "In value for SEQUENCE component `%s'",
4397 value_dispname_str);
4398 Value *comp_value = nv->get_value();
4399 comp_value->set_my_governor(type);
4400 type->chk_this_value_ref(comp_value);
4401 self_ref |= type->chk_this_value(comp_value, lhs, expected_value,
4402 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
4403 }
4404 for (size_t i = 0; i < n_type_comps; i++) {
4405 CompField *cf = u.secho.ctss->get_comp_byIndex(i);
4406 const Identifier& id = cf->get_name();
4407 if (!comp_map.has_key(id.get_name())) {
4408 if (!cf->get_is_optional() && !cf->has_default())
4409 value->error("Mandatory component `%s' is missing from SEQUENCE value",
4410 id.get_dispname().c_str());
4411 else if (cf->get_is_optional() && implicit_omit)
4412 value->add_se_comp(new NamedValue(new Identifier(id),
4413 new Value(Value::V_OMIT)));
4414 }
4415 }
4416 comp_map.clear();
4417 return self_ref;
4418 }
4419
4420 bool Type::chk_this_value_Set_A(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4421 namedbool implicit_omit)
4422 {
4423 bool self_ref = false;
4424 map<string, NamedValue> comp_map;
4425 size_t n_type_comps = u.secho.ctss->get_nof_comps();
4426 size_t n_value_comps = value->get_nof_comps();
4427 for(size_t v_i = 0; v_i < n_value_comps; v_i++) {
4428 NamedValue *nv = value->get_se_comp_byIndex(v_i);
4429 const Identifier& value_id = nv->get_name();
4430 const string& value_name = value_id.get_name();
4431 const char *value_dispname_str = value_id.get_dispname().c_str();
4432 if (!u.secho.ctss->has_comp_withName(value_id)) {
4433 value->error("Reference to non-existent component `%s' of SET type "
4434 "`%s'", value_dispname_str, get_typename().c_str());
4435 nv->note("%s", actual_fields(*this).c_str());
4436 continue;
4437 } else if (comp_map.has_key(value_name)) {
4438 nv->error("Duplicate SET component `%s'", value_dispname_str);
4439 comp_map[value_name]->note("Component `%s' is already given here",
4440 value_dispname_str);
4441 } else comp_map.add(value_name, nv);
4442 Type *type =
4443 u.secho.ctss->get_comp_byName(value_id)->get_type();
4444 Value *comp_value = nv->get_value();
4445 Error_Context cntxt(nv, "In value for SET component `%s'",
4446 value_dispname_str);
4447 comp_value->set_my_governor(type);
4448 type->chk_this_value_ref(comp_value);
4449 self_ref |= type->chk_this_value(comp_value, lhs, expected_value,
4450 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
4451 }
4452 for (size_t i = 0; i < n_type_comps; i++) {
4453 CompField *cf = u.secho.ctss->get_comp_byIndex(i);
4454 const Identifier& id = cf->get_name();
4455 if (!comp_map.has_key(id.get_name())) {
4456 if (!cf->get_is_optional() && !cf->has_default())
4457 value->error("Mandatory component `%s' is missing from SET value",
4458 id.get_dispname().c_str());
4459 else if (cf->get_is_optional() && implicit_omit)
4460 value->add_se_comp(new NamedValue(new Identifier(id),
4461 new Value(Value::V_OMIT)));
4462 }
4463 }
4464 comp_map.clear();
4465 return self_ref;
4466 }
4467
4468 bool Type::chk_this_value_SeOf(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4469 namedbool incomplete_allowed, namedbool implicit_omit)
4470 {
4471 bool self_ref = false;
4472 const char *valuetypename;
4473 if (value->is_asn1()) {
4474 if (typetype == T_SEQOF) valuetypename = "SEQUENCE OF";
4475 else valuetypename = "SET OF";
4476 } else {
4477 if (typetype == T_SEQOF) valuetypename = "record of";
4478 else valuetypename = "set of";
4479 }
4480 if (value->get_valuetype() == Value::V_UNDEF_BLOCK) {
4481 if (typetype == T_SEQOF) value->set_valuetype(Value::V_SEQOF);
4482 else value->set_valuetype(Value::V_SETOF);
4483 } // if V_UNDEF
4484 switch (value->get_valuetype()) {
4485 case Value::V_SEQOF:
4486 if (typetype == T_SETOF) value->set_valuetype(Value::V_SETOF);
4487 // no break
4488 case Value::V_SETOF: {
4489 if (!value->is_indexed()) {
4490 for (size_t i = 0; i < value->get_nof_comps(); i++) {
4491 Value *v_comp = value->get_comp_byIndex(i);
4492 Error_Context cntxt(v_comp, "In component #%lu",
4493 (unsigned long)(i + 1));
4494 v_comp->set_my_governor(u.seof.ofType);
4495 if (v_comp->get_valuetype() == Value::V_NOTUSED) {
4496 if (!incomplete_allowed)
4497 v_comp->error("Not used symbol `-' is not allowed in this "
4498 "context");
4499 } else {
4500 u.seof.ofType->chk_this_value_ref(v_comp);
4501 self_ref |= u.seof.ofType->chk_this_value(v_comp, lhs, expected_value,
4502 incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
4503 }
4504 }
4505 } else {
4506 // Only constant values with constant indicies can be checked at
4507 // compile time. Constant expressions evaluated.
4508 bool check_holes = expected_value == EXPECTED_CONSTANT;
4509 Int max_index = -1;
4510 map<Int, Int> index_map;
4511 for (size_t i = 0; i < value->get_nof_comps(); i++) {
4512 Error_Context cntxt(this, "In component #%lu",
4513 (unsigned long)(i + 1));
4514 Value *val = value->get_comp_byIndex(i);
4515 Value *index = value->get_index_byIndex(i);
4516 index->chk_expr_int(expected_value);
4517 if (index->get_valuetype() != Value::V_ERROR &&
4518 index->get_value_refd_last()->get_valuetype() == Value::V_INT) {
4519 const int_val_t *index_int = index->get_value_refd_last()
4520 ->get_val_Int();
4521 if (*index_int > INT_MAX) {
4522 index->error("An integer value less than `%d' was expected for "
4523 "indexing type `%s' instead of `%s'", INT_MAX,
4524 get_typename().c_str(),
4525 (index_int->t_str()).c_str());
4526 index->set_valuetype(Value::V_ERROR);
4527 check_holes = false;
4528 } else {
4529 Int index_val = index_int->get_val();
4530 if (index_val < 0) {
4531 index->error("A non-negative integer value was expected for "
4532 "indexing type `%s' instead of `%s'",
4533 get_typename().c_str(),
4534 Int2string(index_val).c_str());
4535 index->set_valuetype(Value::V_ERROR);
4536 check_holes = false;
4537 } else if (index_map.has_key(index_val)) {
4538 index->error("Duplicate index value `%s' for components `%s' "
4539 "and `%s'", Int2string(index_val).c_str(),
4540 Int2string((Int)i + 1).c_str(),
4541 Int2string(*index_map[index_val]).c_str());
4542 index->set_valuetype(Value::V_ERROR);
4543 check_holes = false;
4544 } else {
4545 index_map.add(index_val, new Int((Int)i + 1));
4546 if (max_index < index_val)
4547 max_index = index_val;
4548 }
4549 }
4550 } else {
4551 // The index cannot be determined.
4552 check_holes = false;
4553 }
4554 val->set_my_governor(u.seof.ofType);
4555 u.seof.ofType->chk_this_value_ref(val);
4556 self_ref |= u.seof.ofType->chk_this_value(val, lhs, expected_value,
4557 incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK);
4558 }
4559 if (check_holes) {
4560 if ((size_t)max_index != index_map.size() - 1) {
4561 value->error("It's not allowed to create hole(s) in constant "
4562 "values");
4563 value->set_valuetype(Value::V_ERROR);
4564 }
4565 }
4566 for (size_t i = 0; i < index_map.size(); i++)
4567 delete index_map.get_nth_elem(i);
4568 index_map.clear();
4569 }
4570 break; }
4571 default:
4572 value->error("%s value was expected", valuetypename);
4573 value->set_valuetype(Value::V_ERROR);
4574 break;
4575 }
4576 return self_ref;
4577 }
4578
4579 void Type::chk_this_value_Verdict(Value *value)
4580 {
4581 Value *v = value->get_value_refd_last();
4582 switch (v->get_valuetype()) {
4583 case Value::V_VERDICT:
4584 break;
4585 default:
4586 value->error("verdict value was expected");
4587 value->set_valuetype(Value::V_ERROR);
4588 break;
4589 }
4590 }
4591
4592 /** \todo enhance to handle activate */
4593 void Type::chk_this_value_Default(Value *value)
4594 {
4595 switch (value->get_valuetype()) {
4596 case Value::V_TTCN3_NULL:
4597 value->set_valuetype(Value::V_DEFAULT_NULL);
4598 break;
4599 default:
4600 value->error("default value was expected");
4601 value->set_valuetype(Value::V_ERROR);
4602 break;
4603 }
4604 }
4605
4606 bool Type::chk_this_value_Array(Value *value, Common::Assignment *lhs, expected_value_t expected_value,
4607 namedbool incomplete_allowed, namedbool implicit_omit)
4608 {
4609 bool self_ref = false;
4610 switch (value->get_valuetype()) {
4611 case Value::V_SEQOF:
4612 value->set_valuetype(Value::V_ARRAY);
4613 // no break
4614 case Value::V_ARRAY: {
4615 size_t n_value_comps = value->get_nof_comps();
4616 Ttcn::ArrayDimension *dim = u.array.dimension;
4617 if (!value->is_indexed()) {
4618 // Value-list notation.
4619 if (!dim->get_has_error()) {
4620 size_t array_size = dim->get_size();
4621 if (array_size != n_value_comps)
4622 value->error("Too %s elements in the array value: %lu was "
4623 "expected instead of %lu",
4624 array_size > n_value_comps ? "few" : "many",
4625 (unsigned long)array_size,
4626 (unsigned long)n_value_comps);
4627 }
4628 for (size_t i = 0; i < n_value_comps; i++) {
4629 Error_Context cntxt(this, "In array element %lu",
4630 (unsigned long)(i + 1));
4631 Value *v_comp = value->get_comp_byIndex(i);
4632 v_comp->set_my_governor(u.array.element_type);
4633 if (v_comp->get_valuetype() == Value::V_NOTUSED) {
4634 if (!incomplete_allowed)
4635 v_comp->error("Not used symbol `-' is not allowed in this "
4636 "context");
4637 } else {
4638 u.array.element_type->chk_this_value_ref(v_comp);
4639 self_ref |= u.array.element_type->chk_this_value(v_comp, lhs,
4640 expected_value, incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK,
4641 implicit_omit);
4642 }
4643 }
4644 } else {
4645 // Indexed-list notation.
4646 bool array_size_known = !dim->get_has_error();
4647 bool check_holes = array_size_known
4648 && expected_value == EXPECTED_CONSTANT;
4649 size_t array_size = 0;
4650 if (array_size_known) array_size = dim->get_size();
4651 map<Int, Int> index_map;
4652 for (size_t i = 0; i < n_value_comps; i++) {
4653 Error_Context cntxt(this, "In array element #%lu",
4654 (unsigned long)(i + 1));
4655 Value *val = value->get_comp_byIndex(i);
4656 Value *index = value->get_index_byIndex(i);
4657 dim->chk_index(index, expected_value);
4658 if (index->get_value_refd_last()->get_valuetype() == Value::V_INT) {
4659 const int_val_t *index_int = index->get_value_refd_last()
4660 ->get_val_Int();
4661 if (*index_int > INT_MAX) {
4662 index->error("An integer value less than `%d' was expected for "
4663 "indexing type `%s' instead of `%s'", INT_MAX,
4664 get_typename().c_str(),
4665 (index_int->t_str()).c_str());
4666 index->set_valuetype(Value::V_ERROR);
4667 check_holes = false;
4668 } else {
4669 // Index overflows/underflows are already checked by
4670 // ArrayDimensions::chk_index() at this point. The only thing
4671 // we need to check is the uniqueness of constant index values.
4672 Int index_val = index_int->get_val();
4673 if (index_map.has_key(index_val)) {
4674 index->error("Duplicate index value `%s' for components `%s' "
4675 "and `%s'", Int2string(index_val).c_str(),
4676 Int2string((Int)i + 1).c_str(),
4677 Int2string(*index_map[index_val]).c_str());
4678 index->set_valuetype(Value::V_ERROR);
4679 check_holes = false;
4680 } else {
4681 index_map.add(index_val, new Int((Int)i + 1));
4682 }
4683 }
4684 } else {
4685 check_holes = false;
4686 }
4687 val->set_my_governor(u.array.element_type);
4688 u.array.element_type->chk_this_value_ref(val);
4689 self_ref |= u.array.element_type->chk_this_value(val, lhs, expected_value,
4690 incomplete_allowed, OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit);
4691 }
4692 if (check_holes) {
4693 if (index_map.size() < array_size) {
4694 // It's a constant array assigned with constant index values. The
4695 // # of constant index values doesn't reach the size of the array.
4696 value->error("It's not allowed to create hole(s) in constant "
4697 "values");
4698 value->set_valuetype(Value::V_ERROR);
4699 }
4700 }
4701 for (size_t i = 0; i < index_map.size(); i++)
4702 delete index_map.get_nth_elem(i);
4703 index_map.clear();
4704 }
4705 break; }
4706 default:
4707 value->error("array value was expected");
4708 value->set_valuetype(Value::V_ERROR);
4709 break;
4710 }
4711
4712 return self_ref;
4713 }
4714
4715 bool Type::chk_this_value_Signature(Value *value, Common::Assignment *lhs,
4716 expected_value_t expected_value,
4717 namedbool incomplete_allowed)
4718 {
4719 bool self_ref = false;
4720 switch(value->get_valuetype()) {
4721 case Value::V_SEQOF:
4722 value->set_valuetype(Value::V_SEQ);
4723 // no break
4724 case Value::V_SEQ:{
4725 map<string, NamedValue> comp_map;
4726 // it is set to false if we have lost the ordering
4727 bool in_synch = true;
4728 size_t n_type_comps = get_nof_comps();
4729 size_t n_value_comps = value->get_nof_comps();
4730 // for incomplete values
4731 CompField *last_cf = 0;
4732 size_t next_index = 0;
4733 for (size_t v_i = 0; v_i < n_value_comps; v_i++) {
4734 NamedValue *nv = value->get_se_comp_byIndex(v_i);
4735 const Identifier& value_id = nv->get_name();
4736 const string& value_name = value_id.get_name();
4737 const char *value_dispname_str = value_id.get_dispname().c_str();
4738 if (!has_comp_withName(value_id)) {
4739 nv->error("Reference to non-existent parameter `%s' in signature value for "
4740 "type `%s'", value_dispname_str, get_typename().c_str());
4741 in_synch = false;
4742 continue;
4743 } else if (comp_map.has_key(value_name)) {
4744 nv->error("Duplicate signature parameter `%s'", value_dispname_str);
4745 comp_map[value_name]->note("Parameter `%s' is already given here",
4746 value_dispname_str);
4747 in_synch = false;
4748 } else comp_map.add(value_name, nv);
4749 CompField *cf = get_comp_byName(value_id);
4750 // check the ordering of fields
4751 if (in_synch) {
4752 if (incomplete_allowed) {
4753 bool found = false;
4754 for (size_t i = next_index; i < n_type_comps; i++) {
4755 CompField *cf2 = get_comp_byIndex(i);
4756 if (value_name == cf2->get_name().get_name()) {
4757 last_cf = cf2;
4758 next_index = i + 1;
4759 found = true;
4760 break;
4761 }
4762 }
4763 if (!found) {
4764 nv->error("Field `%s' cannot appear after parameter `%s' in signature "
4765 "value", value_dispname_str,
4766 last_cf->get_name().get_dispname().c_str());
4767 in_synch = false;
4768 }
4769 } else {
4770 // the value must be complete
4771 CompField *cf2 = get_comp_byIndex(v_i);
4772 if (cf2 != cf) {
4773 nv->error("Unexpected field `%s' in record value, "
4774 "expecting `%s'", value_dispname_str,
4775 cf2->get_name().get_dispname().c_str());
4776 in_synch = false;
4777 }
4778 }
4779 }
4780 Type *type = cf->get_type();
4781 Value *comp_value = nv->get_value();
4782 comp_value->set_my_governor(type);
4783 Error_Context cntxt(nv, "In value for signature parameter `%s'",
4784 value_dispname_str);
4785 type->chk_this_value_ref(comp_value);
4786 self_ref |= type->chk_this_value(comp_value, lhs, expected_value,
4787 INCOMPLETE_NOT_ALLOWED,
4788 cf->get_is_optional() ? OMIT_ALLOWED : OMIT_NOT_ALLOWED, SUB_CHK);
4789 }
4790 if (!incomplete_allowed) {
4791 for (size_t i = 0; i < u.signature.parameters->get_nof_in_params(); i++) {
4792 const Identifier& id = get_comp_byIndex(i)->get_name(); //u.signature.parameters->get_param_byIndex(n)
4793 if (!comp_map.has_key(id.get_name()) && SignatureParam::PARAM_OUT != u.signature.parameters->get_in_param_byIndex(i)->get_direction()) {
4794 value->error("Field `%s' is missing from signature value",
4795 id.get_dispname().c_str());
4796 }
4797 }
4798 }
4799 comp_map.clear();
4800 break;}
4801 default:
4802 value->error("Signature value was expected for type `%s'",
4803 get_fullname().c_str());
4804 value->set_valuetype(Value::V_ERROR);
4805 break;
4806 }
4807
4808 return self_ref;
4809 }
4810
4811 /** \todo enhance to handle mtc, system, etc. */
4812 void Type::chk_this_value_Component(Value *value)
4813 {
4814 switch (value->get_valuetype()) {
4815 case Value::V_TTCN3_NULL:
4816 value->set_valuetype_COMP_NULL();
4817 break;
4818 case Value::V_EXPR:
4819 if (value->get_optype() == Value::OPTYPE_COMP_NULL)
4820 break; // set_valuetype_COMP_NULL was called already
4821 // no break
4822 default:
4823 value->error("component reference value was expected");
4824 value->set_valuetype(Value::V_ERROR);
4825 break;
4826 }
4827 }
4828
4829 void Type::chk_this_value_FAT(Value *value)
4830 {
4831 switch (value->get_valuetype()) {
4832 case Value::V_TTCN3_NULL:
4833 value->set_valuetype(Value::V_FAT_NULL);
4834 return;
4835 case Value::V_REFER:
4836 // see later
4837 break;
4838 case Value::V_FUNCTION:
4839 case Value::V_ALTSTEP:
4840 case Value::V_TESTCASE:
4841 case Value::V_FAT_NULL:
4842 // This function (chk_this_value_FAT) might have transformed the value
4843 // from V_REFER or V_TTCN3_NULL to one of these. Return now,
4844 // otherwise spurious errors are generated.
4845 return;
4846 default:
4847 switch (typetype) {
4848 case T_FUNCTION:
4849 value->error("Reference to a function or external function was "
4850 "expected");
4851 break;
4852 case T_ALTSTEP:
4853 value->error("Reference to an altstep was expected");
4854 break;
4855 case T_TESTCASE:
4856 value->error("Reference to a testcase was expected");
4857 break;
4858 default:
4859 FATAL_ERROR("Type::chk_this_value_FAT()");
4860 }
4861 value->set_valuetype(Value::V_ERROR);
4862 return;
4863 } // switch valuetype
4864
4865 // Here value->valuetype is V_REFER
4866 Assignment *t_ass = value->get_refered()->get_refd_assignment(false);
4867 if (!t_ass) {
4868 value->set_valuetype(Value::V_ERROR);
4869 return;
4870 }
4871 t_ass->chk();
4872 // check whether refers() points to the right definition
4873 Assignment::asstype_t t_asstype = t_ass->get_asstype();
4874 switch (typetype) {
4875 case T_FUNCTION:
4876 switch (t_asstype) {
4877 case Assignment::A_FUNCTION:
4878 case Assignment::A_FUNCTION_RVAL:
4879 case Assignment::A_FUNCTION_RTEMP:
4880 case Assignment::A_EXT_FUNCTION:
4881 case Assignment::A_EXT_FUNCTION_RVAL:
4882 case Assignment::A_EXT_FUNCTION_RTEMP:
4883 value->set_valuetype(Value::V_FUNCTION, t_ass);
4884 break;
4885 default:
4886 value->error("Reference to a function or external function was "
4887 "expected instead of %s", t_ass->get_description().c_str());
4888 value->set_valuetype(Value::V_ERROR);
4889 return;
4890 }
4891 break;
4892 case T_ALTSTEP:
4893 if (t_ass->get_asstype() == Assignment::A_ALTSTEP) {
4894 value->set_valuetype(Value::V_ALTSTEP, t_ass);
4895 break;
4896 } else {
4897 value->error("Reference to an altstep was expected instead of %s",
4898 t_ass->get_description().c_str());
4899 value->set_valuetype(Value::V_ERROR);
4900 return;
4901 }
4902 case T_TESTCASE:
4903 if (t_ass->get_asstype() == Assignment::A_TESTCASE) {
4904 value->set_valuetype(Value::V_TESTCASE, t_ass);
4905 break;
4906 } else {
4907 value->error("Reference to a testcase was expected instead of %s",
4908 t_ass->get_description().c_str());
4909 value->set_valuetype(Value::V_ERROR);
4910 return;
4911 }
4912 default:
4913 FATAL_ERROR("Type::chk_this_value_FAT()");
4914 }
4915 // comparison of formal parameter lists
4916 {
4917 Error_Context cntxt(value, "In comparing formal parameter lists of "
4918 "type `%s' and %s", get_typename().c_str(),
4919 t_ass->get_description().c_str());
4920 u.fatref.fp_list->chk_compatibility(t_ass->get_FormalParList(),
4921 get_typename().c_str());
4922 }
4923 // comparison of 'runs on' clauses
4924 Type *t_runs_on_type = t_ass->get_RunsOnType();
4925 if (t_runs_on_type) {
4926 if (u.fatref.runs_on.self) {
4927 if (u.fatref.runs_on.ref) {
4928 FATAL_ERROR("Type::chk_this_value_FAT()");
4929 } else { // "runs on self" case
4930 // check against the runs on component type of the scope of the value
4931 Scope* value_scope = value->get_my_scope();
4932 if (!value_scope) FATAL_ERROR("Type::chk_this_value_FAT()");
4933 Ttcn::RunsOnScope *t_ros = value_scope->get_scope_runs_on();
4934 if (t_ros) {
4935 Type *scope_comptype = t_ros->get_component_type();
4936 if (!t_runs_on_type->is_compatible(scope_comptype, NULL)) {
4937 value->error("Runs on clause mismatch: type `%s' has a "
4938 "'runs on self' clause and the current scope expects component "
4939 "type `%s', but %s runs on `%s'", get_typename().c_str(),
4940 scope_comptype->get_typename().c_str(),
4941 t_ass->get_description().c_str(),
4942 t_runs_on_type->get_typename().c_str());
4943 }
4944 } else { // does not have 'runs on' clause
4945 // if the value's scope is a component body then check the runs on
4946 // compatibility using this component type as the scope
4947 ComponentTypeBody* ct_body =
4948 dynamic_cast<ComponentTypeBody*>(value_scope);
4949 if (ct_body) {
4950 if (!t_runs_on_type->is_compatible(ct_body->get_my_type(), NULL)) {
4951 value->error("Runs on clause mismatch: type `%s' has a "
4952 "'runs on self' clause and the current component definition "
4953 "is of type `%s', but %s runs on `%s'",
4954 get_typename().c_str(),
4955 ct_body->get_my_type()->get_typename().c_str(),
4956 t_ass->get_description().c_str(),
4957 t_runs_on_type->get_typename().c_str());
4958 }
4959 } else {
4960 value->error("Type `%s' has a 'runs on self' clause and the "
4961 "current scope does not have a 'runs on' clause, "
4962 "but %s runs on `%s'", get_typename().c_str(),
4963 t_ass->get_description().c_str(),
4964 t_runs_on_type->get_typename().c_str());
4965 }
4966 }
4967 }
4968 } else {
4969 if (u.fatref.runs_on.ref) {
4970 if (u.fatref.runs_on.type &&
4971 !t_runs_on_type->is_compatible(u.fatref.runs_on.type, NULL)) {
4972 value->error("Runs on clause mismatch: type `%s' expects component "
4973 "type `%s', but %s runs on `%s'", get_typename().c_str(),
4974 u.fatref.runs_on.type->get_typename().c_str(),
4975 t_ass->get_description().c_str(),
4976 t_runs_on_type->get_typename().c_str());
4977 }
4978 } else {
4979 value->error("Type `%s' does not have 'runs on' clause, but %s runs "
4980 "on `%s'", get_typename().c_str(), t_ass->get_description().c_str(),
4981 t_runs_on_type->get_typename().c_str());
4982 }
4983 }
4984 }
4985 if (typetype == T_TESTCASE) {
4986 // comparison of system clauses
4987 Ttcn::Def_Testcase *t_testcase = dynamic_cast<Ttcn::Def_Testcase*>(t_ass);
4988 if (!t_testcase) FATAL_ERROR("Type::chk_this_value_FAT()");
4989 Type *t_system_type = t_testcase->get_SystemType();
4990 // if the system clause is missing we shall examine the component type
4991 // that is given in the 'runs on' clause
4992 if (!t_system_type) t_system_type = t_runs_on_type;
4993 Type *my_system_type =
4994 u.fatref.system.ref ? u.fatref.system.type : u.fatref.runs_on.type;
4995 if (t_system_type && my_system_type &&
4996 !t_system_type->is_compatible(my_system_type, NULL)) {
4997 value->error("System clause mismatch: testcase type `%s' expects "
4998 "component type `%s', but %s has `%s'", get_typename().c_str(),
4999 my_system_type->get_typename().c_str(),
5000 t_ass->get_description().c_str(),
5001 t_system_type->get_typename().c_str());
5002 }
5003 } else if (typetype == T_FUNCTION) {
5004 // comparison of return types
5005 bool t_returns_template = false;
5006 switch (t_asstype) {
5007 case Assignment::A_FUNCTION:
5008 case Assignment::A_EXT_FUNCTION:
5009 if (u.fatref.return_type) {
5010 value->error("Type `%s' expects a function or external function "
5011 "that returns a %s of type `%s', but %s does not have return type",
5012 get_typename().c_str(),
5013 u.fatref.returns_template ? "template" : "value",
5014 u.fatref.return_type->get_typename().c_str(),
5015 t_ass->get_description().c_str());
5016 }
5017 break;
5018 case Assignment::A_FUNCTION_RTEMP:
5019 case Assignment::A_EXT_FUNCTION_RTEMP: {
5020 // comparison of template restrictions
5021 Ttcn::Def_Function_Base* dfb =
5022 dynamic_cast<Ttcn::Def_Function_Base*>(t_ass);
5023 if (!dfb) FATAL_ERROR("Type::chk_this_value_FAT()");
5024 template_restriction_t refd_tr = dfb->get_template_restriction();
5025 if (refd_tr!=u.fatref.template_restriction) {
5026 value->error("Type `%s' expects a function or external function "
5027 "that returns a template with %s restriction, "
5028 "but %s returns a template with %s restriction",
5029 get_typename().c_str(),
5030 u.fatref.template_restriction==TR_NONE ? "no" :
5031 Template::get_restriction_name(u.fatref.template_restriction),
5032 t_ass->get_description().c_str(),
5033 refd_tr==TR_NONE ? "no" : Template::get_restriction_name(refd_tr));
5034 }
5035 }
5036 t_returns_template = true;
5037 // no break
5038 case Assignment::A_FUNCTION_RVAL:
5039 case Assignment::A_EXT_FUNCTION_RVAL:
5040 if (u.fatref.return_type) {
5041 Type *t_return_type = t_ass->get_Type();
5042 if (!u.fatref.return_type->is_identical(t_return_type)) {
5043 value->error("Return type mismatch: type `%s' expects a function "
5044 "or external function that returns a %s of type `%s', but %s "
5045 "returns a %s of type `%s'", get_typename().c_str(),
5046 u.fatref.returns_template ? "template" : "value",
5047 u.fatref.return_type->get_typename().c_str(),
5048 t_ass->get_description().c_str(),
5049 t_returns_template ? "template" : "value",
5050 t_return_type->get_typename().c_str());
5051 } else if (u.fatref.return_type->get_sub_type() && t_return_type->get_sub_type() &&
5052 (u.fatref.return_type->get_sub_type()->get_subtypetype()==t_return_type->get_sub_type()->get_subtypetype()) &&
5053 (!u.fatref.return_type->get_sub_type()->is_compatible(t_return_type->get_sub_type()))) {
5054 // TODO: maybe equivalence should be checked, or maybe that is too strict
5055 value->error("Return type subtype mismatch: subtype %s has no common value with subtype %s",
5056 u.fatref.return_type->get_sub_type()->to_string().c_str(),
5057 t_return_type->get_sub_type()->to_string().c_str());
5058 } else if (u.fatref.returns_template != t_returns_template) {
5059 value->error("Type `%s' expects a function or external function "
5060 "that returns a %s of type `%s', but %s returns a %s",
5061 get_typename().c_str(),
5062 u.fatref.returns_template ? "template" : "value",
5063 u.fatref.return_type->get_typename().c_str(),
5064 t_ass->get_description().c_str(),
5065 t_returns_template ? "template" : "value");
5066 }
5067 } else {
5068 value->error("Type `%s' expects a function or external function "
5069 "without return type, but %s returns a %s of type `%s'",
5070 get_typename().c_str(), t_ass->get_description().c_str(),
5071 t_returns_template ? "template" : "value",
5072 t_ass->get_Type()->get_typename().c_str());
5073 }
5074 break;
5075 default:
5076 FATAL_ERROR("Type::chk_this_value_FAT()");
5077 }
5078 }
5079 }
5080
5081 void Type::chk_this_template_length_restriction(Template *t)
5082 {
5083 Ttcn::LengthRestriction *lr = t->get_length_restriction();
5084 if (!lr) FATAL_ERROR("Type::chk_this_template_length_restriction()");
5085 // first check the length restriction itself
5086 lr->chk(EXPECTED_DYNAMIC_VALUE);
5087 if (is_ref()) {
5088 /** \todo check lr against the length subtype constraint of this */
5089 get_type_refd()->chk_this_template_length_restriction(t);
5090 return;
5091 }
5092 typetype_t tt = get_typetype_ttcn3(typetype);
5093 switch (tt) {
5094 case T_ERROR:
5095 case T_PORT:
5096 // return silently, the type of the template is erroneous anyway
5097 return;
5098 case T_ARRAY:
5099 lr->chk_array_size(u.array.dimension);
5100 /* no break */
5101 case T_BSTR:
5102 case T_HSTR:
5103 case T_OSTR:
5104 case T_CSTR:
5105 case T_USTR:
5106 case T_SETOF:
5107 case T_SEQOF:
5108 // length restriction is allowed for these types
5109 break;
5110 default:
5111 lr->error("Length restriction cannot be used in a template of type `%s'",
5112 get_typename().c_str());
5113 return;
5114 }
5115 // check whether the number of elements in t is in accordance with lr
5116 Template *t_last = t->get_template_refd_last();
5117 switch (t_last->get_templatetype()) {
5118 case Ttcn::Template::OMIT_VALUE:
5119 lr->error("Length restriction cannot be used with omit value");
5120 break;
5121 case Ttcn::Template::SPECIFIC_VALUE: {
5122 Value *v_last = t_last->get_specific_value()->get_value_refd_last();
5123 switch (v_last->get_valuetype()) {
5124 case Value::V_BSTR:
5125 if (tt == T_BSTR)
5126 lr->chk_nof_elements(v_last->get_val_strlen(), false, *t, "string");
5127 break;
5128 case Value::V_HSTR:
5129 if (tt == T_HSTR)
5130 lr->chk_nof_elements(v_last->get_val_strlen(), false, *t, "string");
5131 break;
5132 case Value::V_OSTR:
5133 if (tt == T_OSTR)
5134 lr->chk_nof_elements(v_last->get_val_strlen(), false, *t, "string");
5135 break;
5136 case Value::V_CSTR:
5137 if (tt == T_CSTR || tt == T_USTR)
5138 lr->chk_nof_elements(v_last->get_val_strlen(), false, *t, "string");
5139 break;
5140 case Value::V_USTR:
5141 if (tt == T_USTR)
5142 lr->chk_nof_elements(v_last->get_val_strlen(), false, *t, "string");
5143 break;
5144 case Value::V_SEQOF:
5145 if (tt == T_SEQOF)
5146 lr->chk_nof_elements(v_last->get_nof_comps(), false, *t, "value");
5147 break;
5148 case Value::V_SETOF:
5149 if (tt == T_SETOF)
5150 lr->chk_nof_elements(v_last->get_nof_comps(), false, *t, "value");
5151 break;
5152 // note: do not check array values
5153 // they are already verified against the array size
5154 case Value::V_OMIT:
5155 lr->error("Length restriction cannot be used with omit value");
5156 default:
5157 // we cannot verify anything on other value types
5158 // they are either correct or not applicable to the type
5159 break;
5160 }
5161 break; }
5162 case Ttcn::Template::TEMPLATE_LIST:
5163 if (tt == T_SEQOF || tt == T_SETOF)
5164 lr->chk_nof_elements(t_last->get_nof_comps_not_anyornone(),
5165 t_last->temps_contains_anyornone_symbol(), *t, "template");
5166 // note: do not check array templates
5167 // they are already verified against the array size
5168 break;
5169 case Ttcn::Template::SUPERSET_MATCH:
5170 if (tt == T_SETOF)
5171 lr->chk_nof_elements(t_last->get_nof_comps_not_anyornone(), true,
5172 *t, "template");
5173 break;
5174 case Ttcn::Template::BSTR_PATTERN:
5175 if (tt == T_BSTR)
5176 lr->chk_nof_elements(t_last->get_min_length_of_pattern(),
5177 t_last->pattern_contains_anyornone_symbol(), *t, "string");
5178 break;
5179 case Ttcn::Template::HSTR_PATTERN:
5180 if (tt == T_HSTR)
5181 lr->chk_nof_elements(t_last->get_min_length_of_pattern(),
5182 t_last->pattern_contains_anyornone_symbol(), *t, "string");
5183 break;
5184 case Ttcn::Template::OSTR_PATTERN:
5185 if (tt == T_OSTR)
5186 lr->chk_nof_elements(t_last->get_min_length_of_pattern(),
5187 t_last->pattern_contains_anyornone_symbol(), *t, "string");
5188 break;
5189 case Ttcn::Template::CSTR_PATTERN:
5190 if (tt == T_CSTR || tt == T_USTR)
5191 lr->chk_nof_elements(t_last->get_min_length_of_pattern(),
5192 t_last->pattern_contains_anyornone_symbol(), *t, "string");
5193 break;
5194 default:
5195 // We cannot verify anything on other matching mechanisms.
5196 // They are either correct or not applicable to the type.
5197 break;
5198 }
5199 }
5200
5201 void Type::chk_this_template_ref(Template *t)
5202 {
5203 switch (t->get_templatetype()) {
5204 case Ttcn::Template::SPECIFIC_VALUE: {
5205 // if (t->get_templatetype() != Ttcn::Template::SPECIFIC_VALUE) return;
5206 Value *v = t->get_specific_value();
5207 chk_this_value_ref(v);
5208 switch (v->get_valuetype()) {
5209 case Value::V_REFD: {
5210 // Do not check the actual parameter list of the reference yet to avoid
5211 // endless recursion in case of embedded circular references.
5212 // The parameter lists will be verified later.
5213 Assignment *ass = v->get_reference()->get_refd_assignment(false);
5214 if (ass) {
5215 switch (ass->get_asstype()) {
5216 case Assignment::A_VAR_TEMPLATE: {
5217 Type* type = ass->get_Type();
5218 switch (type->typetype) {
5219 case T_BSTR:
5220 case T_BSTR_A:
5221 case T_HSTR:
5222 case T_OSTR:
5223 case T_CSTR:
5224 case T_USTR:
5225 case T_UTF8STRING:
5226 case T_NUMERICSTRING:
5227 case T_PRINTABLESTRING:
5228 case T_TELETEXSTRING:
5229 case T_VIDEOTEXSTRING:
5230 case T_IA5STRING:
5231 case T_GRAPHICSTRING:
5232 case T_VISIBLESTRING:
5233 case T_GENERALSTRING:
5234 case T_UNIVERSALSTRING:
5235 case T_BMPSTRING:
5236 case T_UTCTIME:
5237 case T_GENERALIZEDTIME:
5238 case T_OBJECTDESCRIPTOR: {
5239 // TR 921 (indexing of template strings)
5240 Ttcn::FieldOrArrayRefs *subrefs = v->get_reference()
5241 ->get_subrefs();
5242 if (!subrefs) break;
5243 size_t nof_subrefs = subrefs->get_nof_refs();
5244 if (nof_subrefs > 0) {
5245 Ttcn::FieldOrArrayRef *last_ref = subrefs
5246 ->get_ref(nof_subrefs - 1);
5247 if (last_ref->get_type() == Ttcn::FieldOrArrayRef::ARRAY_REF) {
5248 t->error("Reference to %s can not be indexed",
5249 (ass->get_description()).c_str());
5250 t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5251 return;
5252 }
5253 }
5254 break; }
5255 default:
5256 break;
5257 }
5258 }
5259 case Assignment::A_MODULEPAR_TEMP:
5260 case Assignment::A_TEMPLATE:
5261 case Assignment::A_PAR_TEMPL_IN:
5262 case Assignment::A_PAR_TEMPL_OUT:
5263 case Assignment::A_PAR_TEMPL_INOUT:
5264 case Assignment::A_FUNCTION_RTEMP:
5265 case Assignment::A_EXT_FUNCTION_RTEMP:
5266 t->set_templatetype(Ttcn::Template::TEMPLATE_REFD);
5267 default:
5268 break;
5269 }
5270 } else t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5271 break; }
5272 case Value::V_INVOKE: {
5273 Type *t2 = v->get_invoked_type(Type::EXPECTED_TEMPLATE);
5274 if(t2 && t2->get_type_refd_last()->get_returns_template())
5275 t->set_templatetype(Ttcn::Template::TEMPLATE_INVOKE);
5276 break; }
5277 default:
5278 break;
5279 }
5280 break;
5281 }
5282 case Ttcn::Template::TEMPLATE_REFD: {
5283 // Do not check the actual parameter list of the reference yet to avoid
5284 // endless recursion in case of embedded circular references.
5285 // The parameter lists will be verified later.
5286 Assignment *ass = t->get_reference()->get_refd_assignment(false);
5287 if (ass) {
5288 switch (ass->get_asstype()) {
5289 case Assignment::A_VAR_TEMPLATE: {
5290 Type* type = ass->get_Type();
5291 switch (type->typetype) {
5292 case T_BSTR:
5293 case T_BSTR_A:
5294 case T_HSTR:
5295 case T_OSTR:
5296 case T_CSTR:
5297 case T_USTR:
5298 case T_UTF8STRING:
5299 case T_NUMERICSTRING:
5300 case T_PRINTABLESTRING:
5301 case T_TELETEXSTRING:
5302 case T_VIDEOTEXSTRING:
5303 case T_IA5STRING:
5304 case T_GRAPHICSTRING:
5305 case T_VISIBLESTRING:
5306 case T_GENERALSTRING:
5307 case T_UNIVERSALSTRING:
5308 case T_BMPSTRING:
5309 case T_UTCTIME:
5310 case T_GENERALIZEDTIME:
5311 case T_OBJECTDESCRIPTOR: {
5312 // TR 921 (indexing of template strings)
5313 Ttcn::FieldOrArrayRefs *subrefs = t->get_reference()
5314 ->get_subrefs();
5315 if (!subrefs) break;
5316 size_t nof_subrefs = subrefs->get_nof_refs();
5317 if (nof_subrefs > 0) {
5318 Ttcn::FieldOrArrayRef *last_ref = subrefs
5319 ->get_ref(nof_subrefs - 1);
5320 if (last_ref->get_type() == Ttcn::FieldOrArrayRef::ARRAY_REF) {
5321 t->error("Reference to %s can not be indexed",
5322 (ass->get_description()).c_str());
5323 t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5324 return;
5325 }
5326 }
5327 break; }
5328 default:
5329 break;
5330 }
5331 }
5332 case Assignment::A_MODULEPAR_TEMP:
5333 case Assignment::A_TEMPLATE:
5334 case Assignment::A_PAR_TEMPL_IN:
5335 case Assignment::A_PAR_TEMPL_OUT:
5336 case Assignment::A_PAR_TEMPL_INOUT:
5337 case Assignment::A_FUNCTION_RTEMP:
5338 case Assignment::A_EXT_FUNCTION_RTEMP:
5339 t->set_templatetype(Ttcn::Template::TEMPLATE_REFD);
5340 default:
5341 break;
5342 }
5343 } else t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5344 }
5345 break;
5346 default:
5347 return;
5348 }
5349 }
5350
5351 bool Type::chk_this_template_ref_pard(Ttcn::Ref_pard* ref_pard, Common::Assignment* lhs)
5352 {
5353 // Check if the reference on the left hand side of the assignment can be found
5354 // among the parameters
5355 Ttcn::ActualParList* par_list = ref_pard->get_parlist();
5356 if (par_list) {
5357 size_t nof_pars = par_list->get_nof_pars();
5358 for (size_t i = 0; i < nof_pars; ++i) {
5359 Ttcn::ActualPar* par = par_list->get_par(i);
5360 Ttcn::Ref_base* par_ref = 0;
5361 switch(par->get_selection()) {
5362 case Ttcn::ActualPar::AP_TEMPLATE: {
5363 Ttcn::TemplateInstance* temp_ins = par->get_TemplateInstance();
5364 Ttcn::Template* temp = temp_ins->get_Template();
5365 if (temp->get_templatetype() == Ttcn::Template::TEMPLATE_REFD) {
5366 par_ref = temp->get_reference();
5367 }
5368 break;
5369 }
5370 case Ttcn::ActualPar::AP_REF: {
5371 par_ref = par->get_Ref();
5372 break;
5373 }
5374 default:
5375 break;
5376 }
5377
5378 if (par_ref != 0) {
5379 Common::Assignment* ass = par_ref->get_refd_assignment(true); // also check parameters if there are any
5380 if (ass == lhs)
5381 return true;
5382
5383 // In case a parameter is another function call / parametrised template
5384 // check their parameters as well
5385 if (ass->get_asstype() == Assignment::A_FUNCTION_RTEMP ||
5386 ass->get_asstype() == Assignment::A_EXT_FUNCTION_RTEMP ||
5387 ass->get_asstype() == Assignment::A_TEMPLATE) {
5388 ref_pard = dynamic_cast<Ttcn::Ref_pard*>(par_ref);
5389 if (ref_pard && chk_this_template_ref_pard(ref_pard, lhs))
5390 return true;
5391 }
5392 }
5393 }
5394 }
5395 return false;
5396 }
5397
5398 bool Type::chk_this_template_generic(Template *t, namedbool incomplete_allowed,
5399 namedbool allow_omit, namedbool allow_any_or_omit, namedbool sub_chk,
5400 namedbool implicit_omit, Common::Assignment *lhs)
5401 {
5402 bool self_ref = false;
5403 if (!allow_omit && t->get_template_refd_last()->get_templatetype() ==
5404 Ttcn::Template::OMIT_VALUE) {
5405 t->error("`omit' value is not allowed in this context");
5406 }
5407 if (!allow_any_or_omit && t->get_template_refd_last()->get_templatetype() ==
5408 Ttcn::Template::ANY_OR_OMIT) {
5409 t->warning("Using `*' for mandatory field");
5410 }
5411
5412 Ttcn::Template::templatetype_t temptype = t->get_templatetype();
5413 switch(temptype) {
5414 case Ttcn::Template::TEMPLATE_ERROR:
5415 break;
5416 case Ttcn::Template::TEMPLATE_NOTUSED:
5417 case Ttcn::Template::OMIT_VALUE:
5418 case Ttcn::Template::ANY_VALUE:
5419 case Ttcn::Template::ANY_OR_OMIT: {
5420 Type *type=get_type_refd_last();
5421 if (type->get_typetype() == T_SIGNATURE)
5422 t->error("Generic wildcard `%s' cannot be used for signature `%s'",
5423 t->get_templatetype_str(), type->get_fullname().c_str());
5424 break;}
5425 case Ttcn::Template::VALUE_LIST_ALL_FROM:
5426 case Ttcn::Template::ALL_FROM: {
5427 Ttcn::Template *af = t->get_all_from();
5428 switch (af->get_templatetype()) {
5429 case Ttcn::Template::SPECIFIC_VALUE: {
5430 Value *v = af->get_specific_value();
5431 v->set_lowerid_to_ref();
5432 Reference *ref = v->get_reference();
5433 Assignment *ass = ref->get_refd_assignment(true); // also check parameters if there are any
5434 if (!ass) break; // probably erroneous
5435 //warning("asstype %d", ass->get_asstype());
5436
5437 switch (ass->get_asstype()) {
5438 case Assignment::A_VAR:
5439 case Assignment::A_PAR_VAL_IN:
5440 case Assignment::A_PAR_VAL_INOUT:
5441 case Assignment::A_MODULEPAR:
5442 case Assignment::A_CONST:
5443 case Assignment::A_MODULEPAR_TEMP:
5444 break; // acceptable
5445 case Assignment::A_VAR_TEMPLATE:
5446 case Assignment::A_PAR_TEMPL_IN:
5447 case Assignment::A_PAR_TEMPL_INOUT:
5448 if (ass == lhs)
5449 self_ref = true;
5450 break; // acceptable
5451 case Assignment::A_FUNCTION_RVAL:
5452 case Assignment::A_EXT_FUNCTION_RVAL:
5453 case Assignment::A_FUNCTION_RTEMP:
5454 case Assignment::A_EXT_FUNCTION_RTEMP:
5455 case Assignment::A_TEMPLATE: {
5456 Ttcn::Ref_pard* ref_pard = dynamic_cast<Ttcn::Ref_pard*>(ref);
5457 if (ref_pard)
5458 self_ref |= chk_this_template_ref_pard(ref_pard, lhs);
5459 break; // acceptable
5460 }
5461 default:
5462 error("A %s cannot be used as the target of `all from'",
5463 ass->get_assname());
5464 break;
5465 }
5466 //self_ref |= chk_this_value(v, lhs, EXPECTED_TEMPLATE, incomplete_allowed,
5467 // allow_omit, sub_chk, implicit_omit, NOT_STR_ELEM /* ?? */);
5468 break; }
5469
5470 default:
5471 error("The target of an 'all from' must be a specific value template, not a %s",
5472 af->get_templatetype_str());
5473 break;
5474 }
5475
5476 break; }
5477 case Ttcn::Template::VALUE_LIST:
5478 case Ttcn::Template::COMPLEMENTED_LIST: {
5479 size_t nof_comps = t->get_nof_comps();
5480 for (size_t i = 0; i < nof_comps; i++) {
5481 Template* t_comp = t->get_temp_byIndex(i);
5482 Error_Context cntxt(t, "In list item %lu", (unsigned long) (i + 1));
5483 t_comp->set_my_governor(this);
5484 chk_this_template_ref(t_comp);
5485 self_ref |= chk_this_template_generic(t_comp, INCOMPLETE_NOT_ALLOWED,
5486 omit_in_value_list ? allow_omit : OMIT_NOT_ALLOWED,
5487 ANY_OR_OMIT_ALLOWED, sub_chk, implicit_omit, lhs);
5488 if(temptype==Ttcn::Template::COMPLEMENTED_LIST &&
5489 t_comp->get_template_refd_last()->get_templatetype() ==
5490 Ttcn::Template::ANY_OR_OMIT)
5491 t_comp->warning("`*' in complemented list."
5492 " This template will not match anything");
5493 }
5494 break;}
5495 case Ttcn::Template::SPECIFIC_VALUE: {
5496 Value *v = t->get_specific_value();
5497 v->set_my_governor(this);
5498 self_ref |= chk_this_value(v, lhs, EXPECTED_TEMPLATE, incomplete_allowed,
5499 allow_omit, SUB_CHK);
5500 break; }
5501 case Ttcn::Template::TEMPLATE_INVOKE: {
5502 t->chk_invoke();
5503 Type *governor = t->get_expr_governor(EXPECTED_DYNAMIC_VALUE);
5504 if(!governor)
5505 t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5506 else if (!is_compatible(governor, NULL)) {
5507 t->error("Type mismatch: a value or template of type `%s' was "
5508 "expected instead of `%s'", get_typename().c_str(),
5509 governor->get_typename().c_str());
5510 t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5511 }
5512 break; }
5513 case Ttcn::Template::TEMPLATE_REFD:
5514 self_ref = chk_this_refd_template(t, lhs);
5515 break;
5516 default:
5517 self_ref = chk_this_template(t, incomplete_allowed, sub_chk, implicit_omit, lhs);
5518 break;
5519 }
5520 if (t->get_length_restriction()) chk_this_template_length_restriction(t);
5521 if (!allow_omit && t->get_ifpresent())
5522 t->error("`ifpresent' is not allowed here");
5523 if(sub_chk && temptype != Ttcn::Template::PERMUTATION_MATCH) {
5524 /* Note: A "permuation" itself has no type - it is just a fragment. */
5525 if(sub_type!=NULL) sub_type->chk_this_template_generic(t);
5526 }
5527
5528 return self_ref;
5529 }
5530
5531 bool Type::chk_this_refd_template(Template *t, Common::Assignment *lhs)
5532 {
5533 if (t->get_templatetype() != Template::TEMPLATE_REFD) return false;
5534 Reference *ref = t->get_reference();
5535 Assignment *ass = ref->get_refd_assignment();
5536 if (!ass) FATAL_ERROR("Type::chk_this_refd_template()");
5537 ass->chk();
5538
5539 Type *governor = ass->get_Type()
5540 ->get_field_type(ref->get_subrefs(), EXPECTED_DYNAMIC_VALUE);
5541 if (!governor) {
5542 t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5543 } else {
5544 TypeCompatInfo info(t->get_my_scope()->get_scope_mod(), this, governor,
5545 true, false, true);
5546 if (ref->get_subrefs()) info.set_str2_elem(ref->get_subrefs()->refers_to_string_element());
5547 TypeChain l_chain;
5548 TypeChain r_chain;
5549 if (!is_compatible(governor, &info, &l_chain, &r_chain)) {
5550 Type *type = get_type_refd_last();
5551 switch (type->typetype) {
5552 case T_PORT:
5553 // Port templates do not exist, remain silent.
5554 break;
5555 case T_SIGNATURE:
5556 t->error("Type mismatch: a signature template of type `%s' was "
5557 "expected instead of `%s'", get_typename().c_str(),
5558 governor->get_typename().c_str());
5559 break;
5560 default:
5561 if (info.is_subtype_error()) {
5562 t->error("%s", info.get_subtype_error().c_str());
5563 } else if (!info.is_erroneous()) {
5564 t->error("Type mismatch: a value or template of type `%s' was "
5565 "expected instead of `%s'", get_typename().c_str(),
5566 governor->get_typename().c_str());
5567 } else {
5568 t->error("%s", info.get_error_str_str().c_str());
5569 }
5570 break;
5571 }
5572 t->set_templatetype(Ttcn::Template::TEMPLATE_ERROR);
5573 } else {
5574 // Detect circular references.
5575 t->get_template_refd_last();
5576
5577 if (info.needs_conversion()) t->set_needs_conversion();
5578 }
5579 }
5580 return (lhs == ass);
5581 }
5582
5583 bool Type::chk_this_template(Template *t, namedbool is_modified, namedbool,
5584 namedbool implicit_omit, Common::Assignment *lhs)
5585 {
5586 bool self_ref = false;
5587 Type *t_last = get_type_refd_last();
5588 t->set_my_governor(t_last);
5589
5590 switch(t_last->typetype) {
5591 case T_ERROR:
5592 break;
5593 case T_NULL:
5594 case T_BOOL:
5595 case T_OID:
5596 case T_ROID:
5597 case T_ANY:
5598 case T_VERDICT:
5599 case T_COMPONENT:
5600 case T_DEFAULT:
5601 t_last->chk_this_template_builtin(t);
5602 break;
5603 case T_BSTR_A:
5604 case T_BSTR:
5605 case T_HSTR:
5606 case T_OSTR:
5607 case T_CSTR:
5608 case T_USTR:
5609 case T_UTF8STRING:
5610 case T_NUMERICSTRING:
5611 case T_PRINTABLESTRING:
5612 case T_TELETEXSTRING:
5613 case T_VIDEOTEXSTRING:
5614 case T_IA5STRING:
5615 case T_GRAPHICSTRING:
5616 case T_VISIBLESTRING:
5617 case T_GENERALSTRING:
5618 case T_UNIVERSALSTRING:
5619 case T_BMPSTRING:
5620 case T_UTCTIME:
5621 case T_GENERALIZEDTIME:
5622 case T_OBJECTDESCRIPTOR:
5623 t_last->chk_this_template_Str(t);
5624 break;
5625 case T_INT:
5626 case T_INT_A:
5627 case T_REAL:
5628 t_last->chk_this_template_Int_Real(t);
5629 break;
5630 case T_ENUM_A:
5631 case T_ENUM_T:
5632 t_last->chk_this_template_Enum(t);
5633 break;
5634 case T_CHOICE_A:
5635 case T_CHOICE_T:
5636 case T_OPENTYPE:
5637 case T_ANYTYPE:
5638 self_ref = t_last->chk_this_template_Choice(t, is_modified, implicit_omit, lhs);
5639 break;
5640 case T_SEQ_A:
5641 case T_SEQ_T:
5642 self_ref = t_last->chk_this_template_Seq(t, is_modified, implicit_omit, lhs);
5643 break;
5644 case T_SET_A:
5645 case T_SET_T:
5646 self_ref = t_last->chk_this_template_Set(t, is_modified, implicit_omit, lhs);
5647 break;
5648 case T_SEQOF:
5649 self_ref = t_last->chk_this_template_SeqOf(t, is_modified, implicit_omit, lhs);
5650 break;
5651 case T_SETOF:
5652 self_ref = t_last->chk_this_template_SetOf(t, is_modified, implicit_omit, lhs);
5653 break;
5654 case T_ARRAY:
5655 self_ref = t_last->chk_this_template_array(t, is_modified, implicit_omit, lhs);
5656 break;
5657 case T_PORT:
5658 t->error("Template cannot be defined for port type `%s'",
5659 get_fullname().c_str());
5660 break;
5661 case T_SIGNATURE:
5662 t_last->chk_this_template_Signature(t, is_modified);
5663 break;
5664 case T_FUNCTION:
5665 case T_ALTSTEP:
5666 case T_TESTCASE:
5667 t_last->chk_this_template_Fat(t);
5668 break;
5669 default:
5670 FATAL_ERROR("Type::chk_this_template()");
5671 } // switch
5672 return self_ref;
5673 }
5674
5675 void Type::chk_this_template_Str(Template *t)
5676 {
5677 typetype_t tt = get_typetype_ttcn3(typetype);
5678 bool report_error = false;
5679 switch (t->get_templatetype()) {
5680 case Ttcn::Template::VALUE_RANGE:
5681 if (tt == T_CSTR || tt == T_USTR) {
5682 Error_Context cntxt(t, "In value range");
5683 Ttcn::ValueRange *vr = t->get_value_range();
5684 Value *v_lower = chk_range_boundary(vr->get_min_v(), "lower", *t);
5685 Value *v_upper = chk_range_boundary(vr->get_max_v(), "upper", *t);
5686 if (v_lower && v_upper) {
5687 // both boundaries are available and have correct type
5688 if (tt == T_CSTR) {
5689 if (v_lower->get_val_str() > v_upper->get_val_str())
5690 t->error("The lower boundary has higher character code than the "
5691 "upper boundary");
5692 } else {
5693 if (v_lower->get_val_ustr() > v_upper->get_val_ustr())
5694 t->error("The lower boundary has higher character code than the "
5695 "upper boundary");
5696 }
5697 }
5698 } else report_error = true;
5699 break;
5700 case Ttcn::Template::BSTR_PATTERN:
5701 if (tt != T_BSTR) report_error = true;
5702 break;
5703 case Ttcn::Template::HSTR_PATTERN:
5704 if (tt != T_HSTR) report_error = true;
5705 break;
5706 case Ttcn::Template::OSTR_PATTERN:
5707 if (tt != T_OSTR) report_error = true;
5708 break;
5709 case Ttcn::Template::CSTR_PATTERN:
5710 if (tt == T_CSTR) {
5711 Ttcn::PatternString *pstr = t->get_cstr_pattern();
5712 Error_Context cntxt(t, "In character string pattern");
5713 pstr->chk_refs();
5714 pstr->join_strings();
5715 if (!pstr->has_refs()) pstr->chk_pattern();
5716 break;
5717 } else if (tt == T_USTR) {
5718 t->set_templatetype(Template::USTR_PATTERN);
5719 t->get_ustr_pattern()
5720 ->set_pattern_type(Ttcn::PatternString::USTR_PATTERN);
5721 // fall through
5722 } else {
5723 report_error = true;
5724 break;
5725 }
5726 // no break
5727 case Ttcn::Template::USTR_PATTERN:
5728 if (tt == T_USTR) {
5729 Ttcn::PatternString *pstr = t->get_ustr_pattern();
5730 Error_Context cntxt(t, "In universal string pattern");
5731 pstr->chk_refs();
5732 pstr->join_strings();
5733 if (!pstr->has_refs()) pstr->chk_pattern();
5734 } else report_error = true;
5735 break;
5736 default:
5737 report_error = true;
5738 break;
5739 }
5740 if (report_error) {
5741 t->error("%s cannot be used for type `%s'", t->get_templatetype_str(),
5742 get_typename().c_str());
5743 }
5744 }
5745
5746 void Type::chk_range_boundary_infinity(Value *v, bool is_upper)
5747 {
5748 if (v) {
5749 v->set_my_governor(this);
5750 {
5751 Error_Context cntxt2(v, "In %s boundary", is_upper ? "upper" : "lower");
5752 chk_this_value_ref(v);
5753 Value *v_last = v->get_value_refd_last(0, EXPECTED_STATIC_VALUE);
5754 if (v_last->get_valuetype() == Value::V_OMIT) {
5755 v->error("`omit' value is not allowed in this context");
5756 v->set_valuetype(Value::V_ERROR);
5757 return;
5758 }
5759 if (sub_type != NULL) {
5760 if (is_upper) {
5761 if (!sub_type->get_root()->is_upper_limit_infinity()) {
5762 v->error("Infinity is not a valid value for type '%s' which has subtype %s",
5763 asString(), sub_type->to_string().c_str());
5764 }
5765 }
5766 else {
5767 if (!sub_type->get_root()->is_lower_limit_infinity()) {
5768 v->error("Infinity is not a valid value for type '%s' which has subtype %s",
5769 asString(), sub_type->to_string().c_str());
5770 }
5771 }
5772 }
5773 }
5774 }
5775 }
5776
5777 Value *Type::chk_range_boundary(Value *v, const char *which,
5778 const Location& loc)
5779 {
5780 typetype_t tt = get_typetype_ttcn3(typetype);
5781 Value *ret_val;
5782 if (v) {
5783 v->set_my_governor(this);
5784 {
5785 Error_Context cntxt2(v, "In %s boundary", which);
5786 chk_this_value_ref(v);
5787 chk_this_value(v, 0, EXPECTED_DYNAMIC_VALUE, INCOMPLETE_NOT_ALLOWED,
5788 OMIT_NOT_ALLOWED, SUB_CHK);
5789 }
5790 ret_val = v->get_value_refd_last();
5791 switch (ret_val->get_valuetype()) {
5792 case Value::V_INT:
5793 if (tt != T_INT) ret_val = 0;
5794 break;
5795 case Value::V_REAL:
5796 if (tt != T_REAL) ret_val = 0;
5797 break;
5798 case Value::V_CSTR:
5799 if (tt != T_CSTR) ret_val = 0;
5800 break;
5801 case Value::V_USTR:
5802 if (tt != T_USTR) ret_val = 0;
5803 break;
5804 default:
5805 // unfoldable or erroneous
5806 ret_val = 0;
5807 break;
5808 }
5809 if ((tt == T_CSTR || tt == T_USTR) && ret_val &&
5810 ret_val->get_val_strlen() != 1) {
5811 v->error("The %s boundary must be a %scharstring value containing a "
5812 "single character", which, tt == T_USTR ? "universal ": "");
5813 ret_val = 0;
5814 }
5815 } else {
5816 // the boundary is + or - infinity
5817 if (tt == T_CSTR || tt == T_USTR) {
5818 loc.error("The %s boundary must be a %scharstring value", which,
5819 tt == T_USTR ? "universal ": "");
5820 }
5821 ret_val = 0;
5822 }
5823 return ret_val;
5824 }
5825
5826 void Type::chk_this_template_builtin(Template *t)
5827 {
5828 t->error("%s cannot be used for type `%s'", t->get_templatetype_str(),
5829 get_typename().c_str());
5830 if (t->get_length_restriction()) t->error("Length restriction is not "
5831 "allowed for type `%s'", get_typename().c_str());
5832 }
5833
5834 void Type::chk_this_template_Int_Real(Template *t)
5835 {
5836 switch (t->get_templatetype()) {
5837 case Ttcn::Template::VALUE_RANGE: {
5838 Error_Context cntxt(t, "In value range");
5839 Ttcn::ValueRange *vr = t->get_value_range();
5840 Value *v_lower = chk_range_boundary(vr->get_min_v(), "lower", *t);
5841 Value *v_upper = chk_range_boundary(vr->get_max_v(), "upper", *t);
5842 if (v_lower && v_upper) {
5843 // both boundaries are available and have correct type
5844 switch (get_typetype_ttcn3(typetype)) {
5845 case T_INT: {
5846 if (*v_lower->get_val_Int() > *v_upper->get_val_Int())
5847 t->error("The lower boundary is higher than the upper boundary");
5848 break; }
5849 case T_REAL:
5850 if (v_lower->get_val_Real() > v_upper->get_val_Real())
5851 t->error("The lower boundary is higher than the upper boundary");
5852 break;
5853 default:
5854 FATAL_ERROR("Type::chk_this_template_Int_Real()");
5855 }
5856 }
5857 if (v_lower && !vr->get_max_v()) {
5858 chk_range_boundary_infinity(v_lower, true);
5859 }
5860 if (!vr->get_min_v() && v_upper) {
5861 chk_range_boundary_infinity(v_upper, false);
5862 }
5863 break;}
5864 default:
5865 t->error("%s cannot be used for type `%s'", t->get_templatetype_str(),
5866 get_typename().c_str());
5867 break;
5868 }
5869 if (t->get_length_restriction()) t->error("Length restriction is not "
5870 "allowed for type `%s'", get_typename().c_str());
5871 }
5872
5873 void Type::chk_this_template_Enum(Template *t)
5874 {
5875 t->error("%s cannot be used for enumerated type `%s'",
5876 t->get_templatetype_str(), get_typename().c_str());
5877 if (t->get_length_restriction()) t->error("Length restriction is not "
5878 "allowed for enumerated type `%s'", get_typename().c_str());
5879 }
5880
5881 bool Type::chk_this_template_Choice(Template *t, namedbool is_modified,
5882 namedbool implicit_omit, Common::Assignment *lhs)
5883 {
5884 bool self_ref = false;
5885 switch (t->get_templatetype()) {
5886 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
5887 size_t nof_nts = t->get_nof_comps();
5888 if (nof_nts != 1) t->error("A template for union type must contain "
5889 "exactly one selected field");
5890 // We check all named templates, even though it is an error
5891 // to have more than one here.
5892 for (size_t i = 0; i < nof_nts; i++) {
5893 Ttcn::NamedTemplate *nt = t->get_namedtemp_byIndex(i);
5894 if (typetype == T_OPENTYPE) {
5895 // allow the alternatives of open types as both lower and upper identifiers
5896 nt->set_name_to_lowercase();
5897 }
5898 const Identifier& nt_name = nt->get_name();
5899
5900 if (!has_comp_withName(nt_name)) {
5901 nt->error("Reference to non-existent field `%s' in union "
5902 "template for type `%s'", nt_name.get_dispname().c_str(),
5903 get_fullname().c_str());
5904 nt->note("%s", actual_fields(*this).c_str());
5905 continue;
5906 }
5907
5908 Type *field_type = get_comp_byName(nt_name)->get_type();
5909 Template *nt_templ = nt->get_template();
5910
5911 Error_Context cntxt(nt_templ, "In template for union field `%s'",
5912 nt_name.get_dispname().c_str());
5913
5914 nt_templ->set_my_governor(field_type);
5915 field_type->chk_this_template_ref(nt_templ);
5916 bool incompl_ok = t->get_completeness_condition_choice(is_modified, nt_name) ==
5917 Ttcn::Template::C_MAY_INCOMPLETE;
5918 self_ref |= field_type->chk_this_template_generic(nt_templ,
5919 (incompl_ok ? INCOMPLETE_ALLOWED : INCOMPLETE_NOT_ALLOWED),
5920 OMIT_NOT_ALLOWED, ANY_OR_OMIT_NOT_ALLOWED, SUB_CHK, implicit_omit, lhs);
5921 }
5922 break;}
5923 default:
5924 t->error("%s cannot be used for union type `%s'",
5925 t->get_templatetype_str(), get_typename().c_str());
5926 break;
5927 }
5928 if (t->get_length_restriction()) t->error("Length restriction is not "
5929 "allowed for union type `%s'", get_typename().c_str());
5930
5931 return self_ref;
5932 }
5933
5934 bool Type::chk_this_template_Seq(Template *t, namedbool is_modified,
5935 namedbool implicit_omit, Common::Assignment *lhs)
5936 {
5937 bool self_ref = false;
5938 size_t n_type_comps = get_nof_comps();
5939 switch (t->get_templatetype()) {
5940 case Ttcn::Template::TEMPLATE_LIST:
5941 // conversion: value list -> assignment notation
5942 t->set_templatetype(Ttcn::Template::NAMED_TEMPLATE_LIST);
5943 // no break
5944 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
5945 map<string, Ttcn::NamedTemplate> comp_map;
5946 // it is set to false if we have lost the ordering
5947 bool in_synch = true;
5948 size_t n_template_comps = t->get_nof_comps();
5949 // the two variables below are used for modified templates only
5950 CompField *last_cf = 0;
5951 size_t next_index = 0;
5952 for (size_t i = 0; i < n_template_comps; i++) {
5953 Ttcn::NamedTemplate *namedtemp = t->get_namedtemp_byIndex(i);
5954 const Identifier& temp_id = namedtemp->get_name();
5955 const string& temp_name = temp_id.get_name();
5956 const char *temp_dispname_str = temp_id.get_dispname().c_str();
5957 if (!has_comp_withName(temp_id)) {
5958 namedtemp->error("Reference to non-existent field `%s' in record "
5959 "template for type `%s'", temp_dispname_str,
5960 get_typename().c_str());
5961 namedtemp->note("%s", actual_fields(*this).c_str());
5962 in_synch = false;
5963 continue;
5964 } else if (comp_map.has_key(temp_name)) {
5965 namedtemp->error("Duplicate record field `%s' in template",
5966 temp_dispname_str);
5967 comp_map[temp_name]->note("Field `%s' is already given here",
5968 temp_dispname_str);
5969 in_synch = false;
5970 } else comp_map.add(temp_name, namedtemp);
5971
5972 CompField *cf = get_comp_byName(temp_id);
5973 if (in_synch) {
5974 if (is_modified) {
5975 // missing fields are allowed, but take care of ordering
5976 bool found = false;
5977 for (size_t j = next_index; j < n_type_comps; j++) {
5978 CompField *cf2 = get_comp_byIndex(j);
5979 if (temp_name == cf2->get_name().get_name()) {
5980 last_cf = cf2;
5981 next_index = j + 1;
5982 found = true;
5983 break;
5984 }
5985 }
5986 if (!found) {
5987 namedtemp->error("Field `%s' cannot appear after field `%s' in "
5988 "a template for record type `%s'", temp_dispname_str,
5989 last_cf->get_name().get_dispname().c_str(),
5990 get_fullname().c_str());
5991 in_synch = false;
5992 }
5993 } else {
5994 // the template must be complete
5995 CompField *cf2 = get_comp_byIndex(i);
5996 if (cf2 != cf) {
5997 if (!cf2->get_is_optional() || !implicit_omit) {
5998 namedtemp->error("Unexpected field `%s' in record template, "
5999 "expecting `%s'", temp_dispname_str,
6000 cf2->get_name().get_dispname().c_str());
6001 in_synch = false;
6002 }
6003 }
6004 }
6005 }
6006 Type *type = cf->get_type();
6007 Template *comp_t = namedtemp->get_template();
6008 Error_Context cntxt(comp_t, "In template for record field `%s'",
6009 temp_dispname_str);
6010 comp_t->set_my_governor(type);
6011 type->chk_this_template_ref(comp_t);
6012 bool is_optional = cf->get_is_optional(); // || cf->has_default()
6013 self_ref |= type->chk_this_template_generic(comp_t, is_modified,
6014 (is_optional ? OMIT_ALLOWED : OMIT_NOT_ALLOWED),
6015 (is_optional ? ANY_OR_OMIT_ALLOWED : ANY_OR_OMIT_NOT_ALLOWED),
6016 SUB_CHK, implicit_omit, lhs);
6017 }
6018 if (!is_modified || implicit_omit) {
6019 // check missing fields
6020 for (size_t i = 0; i < n_type_comps; i++) {
6021 const Identifier& id = get_comp_byIndex(i)->get_name();
6022 if (!comp_map.has_key(id.get_name())) {
6023 if (implicit_omit && get_comp_byIndex(i)->get_is_optional()) {
6024 // do not overwrite base fields
6025 if (!t->get_base_template())
6026 t->add_named_temp(new Ttcn::NamedTemplate(new Identifier(id),
6027 new Template(Template::OMIT_VALUE)));
6028 } else if (!is_modified) {
6029 t->error("Field `%s' is missing from template for record type `%s'",
6030 id.get_dispname().c_str(), get_typename().c_str());
6031 }
6032 }
6033 }
6034 }
6035 comp_map.clear();
6036 break; }
6037 default:
6038 t->error("%s cannot be used for record type `%s'",
6039 t->get_templatetype_str(), get_typename().c_str());
6040 break;
6041 }
6042 if (t->get_length_restriction()) t->error("Length restriction is not "
6043 "allowed for record type `%s'", get_typename().c_str());
6044 return self_ref;
6045 }
6046
6047 bool Type::chk_this_template_Set(Template *t,
6048 namedbool is_modified, namedbool implicit_omit, Common::Assignment *lhs)
6049 {
6050 bool self_ref = false;
6051 size_t n_type_comps = get_nof_comps();
6052 switch (t->get_templatetype()) {
6053 case Ttcn::Template::TEMPLATE_LIST:
6054 if (t->get_nof_comps() > 0) {
6055 t->error("Value list notation is not allowed for set type `%s'",
6056 get_fullname().c_str());
6057 break;
6058 } else if (n_type_comps > 0) {
6059 t->error("A non-empty set template was expected for type `%s'",
6060 get_fullname().c_str());
6061 break;
6062 }
6063 t->set_templatetype(Ttcn::Template::NAMED_TEMPLATE_LIST);
6064 // no break
6065 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
6066 map<string, Ttcn::NamedTemplate> comp_map;
6067 size_t n_template_comps = t->get_nof_comps();
6068 for (size_t i = 0; i < n_template_comps; i++) {
6069 Ttcn::NamedTemplate *namedtemp = t->get_namedtemp_byIndex(i);
6070 const Identifier& temp_id=namedtemp->get_name();
6071 const string& temp_name = temp_id.get_name();
6072 const char *temp_dispname_str = temp_id.get_dispname().c_str();
6073 if (!has_comp_withName(temp_id)) {
6074 namedtemp->error("Reference to non-existent field `%s' in a "
6075 "template for set type `%s'", temp_dispname_str,
6076 get_typename().c_str());
6077 namedtemp->note("%s", actual_fields(*this).c_str());
6078 continue;
6079 } else if (comp_map.has_key(temp_name)) {
6080 namedtemp->error("Duplicate set field `%s' in template",
6081 temp_dispname_str);
6082 comp_map[temp_name]->note("Field `%s' is already given here",
6083 temp_dispname_str);
6084 } else comp_map.add(temp_name, namedtemp);
6085 CompField *cf = get_comp_byName(temp_id);
6086 Type *type = cf->get_type();
6087 Template *comp_t = namedtemp->get_template();
6088 Error_Context cntxt(comp_t, "In template for set field `%s'",
6089 temp_dispname_str);
6090 comp_t->set_my_governor(type);
6091 type->chk_this_template_ref(comp_t);
6092 bool is_optional = cf->get_is_optional();
6093 self_ref |= type->chk_this_template_generic(comp_t,
6094 (is_modified ? INCOMPLETE_ALLOWED : INCOMPLETE_NOT_ALLOWED),
6095 (is_optional ? OMIT_ALLOWED : OMIT_NOT_ALLOWED),
6096 (is_optional ? ANY_OR_OMIT_ALLOWED : ANY_OR_OMIT_NOT_ALLOWED),
6097 SUB_CHK, implicit_omit, lhs);
6098 }
6099 if (!is_modified || implicit_omit) {
6100 // check missing fields
6101 for (size_t i = 0; i < n_type_comps; i++) {
6102 const Identifier& id = get_comp_byIndex(i)->get_name();
6103 if (!comp_map.has_key(id.get_name())) {
6104 if (get_comp_byIndex(i)->get_is_optional() && implicit_omit) {
6105 // do not overwrite base fields
6106 if (!t->get_base_template())
6107 t->add_named_temp(new Ttcn::NamedTemplate(new Identifier(id),
6108 new Template(Template::OMIT_VALUE)));
6109 } else if (!is_modified) {
6110 t->error("Field `%s' is missing from template for set type `%s'",
6111 id.get_dispname().c_str(), get_typename().c_str());
6112 }
6113 }
6114 }
6115 }
6116 comp_map.clear();
6117 break; }
6118 default:
6119 t->error("%s cannot be used for set type `%s'",
6120 t->get_templatetype_str(), get_typename().c_str());
6121 break;
6122 }
6123 if (t->get_length_restriction()) t->error("Length restriction is not "
6124 "allowed for set type `%s'", get_typename().c_str());
6125 return self_ref;
6126 }
6127
6128 bool Type::chk_this_template_SeqOf(Template *t, namedbool is_modified,
6129 namedbool implicit_omit, Common::Assignment *lhs)
6130 {
6131 bool self_ref = false;
6132 switch(t->get_templatetype()) {
6133 case Ttcn::Template::OMIT_VALUE:
6134 if(t->get_length_restriction())
6135 t->warning("Redundant usage of length restriction with `omit'");
6136 break;
6137 case Ttcn::Template::PERMUTATION_MATCH: {
6138 size_t nof_comps = t->get_nof_comps();
6139 for (size_t i = 0; i < nof_comps; i++) {
6140 Template *t_comp = t->get_temp_byIndex(i);
6141 Error_Context cntxt(t_comp, "In element %lu of permutation",
6142 (unsigned long) (i + 1));
6143 t_comp->set_my_governor(u.seof.ofType);
6144 u.seof.ofType->chk_this_template_ref(t_comp);
6145 // the elements of permutation must be always complete
6146 self_ref |= u.seof.ofType->chk_this_template_generic(t_comp,
6147 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
6148 NOT_IMPLICIT_OMIT, lhs);
6149 }
6150 break; }
6151 case Ttcn::Template::TEMPLATE_LIST: {
6152 Ttcn::Template::completeness_t c =
6153 t->get_completeness_condition_seof(is_modified);
6154 Template *t_base;
6155 size_t nof_base_comps;
6156 if (c == Ttcn::Template::C_PARTIAL) {
6157 t_base = t->get_base_template()->get_template_refd_last();
6158 // it is sure that t_base is a TEMPLATE_LIST
6159 nof_base_comps = t_base->get_nof_comps();
6160 } else {
6161 t_base = 0;
6162 nof_base_comps = 0;
6163 }
6164 size_t nof_comps = t->get_nof_comps();
6165 for(size_t i = 0; i < nof_comps; i++) {
6166 Template *t_comp = t->get_temp_byIndex(i);
6167 Error_Context cntxt(t_comp, "In component %lu", (unsigned long)(i+1));
6168 t_comp->set_my_governor(u.seof.ofType);
6169 if (t_base && i < nof_base_comps)
6170 t_comp->set_base_template(t_base->get_temp_byIndex(i));
6171 u.seof.ofType->chk_this_template_ref(t_comp);
6172 switch (t_comp->get_templatetype()) {
6173 case Ttcn::Template::PERMUTATION_MATCH:
6174 // the elements of permutation has to be checked by u.seof.ofType
6175 // the templates within the permutation always have to be complete
6176 self_ref |= chk_this_template_generic(t_comp, INCOMPLETE_NOT_ALLOWED,
6177 OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
6178 implicit_omit, lhs);
6179 break;
6180 case Ttcn::Template::TEMPLATE_NOTUSED:
6181 if (c == Ttcn::Template::C_MUST_COMPLETE) {
6182 t_comp->error("Not used symbol `-' is not allowed in this context");
6183 } else if (c == Ttcn::Template::C_PARTIAL && i >= nof_base_comps) {
6184 t_comp->error("Not used symbol `-' cannot be used here because "
6185 "there is no corresponding element in the base template");
6186 }
6187 break;
6188 default:
6189 bool embedded_modified = (c == Ttcn::Template::C_MAY_INCOMPLETE) ||
6190 (c == Ttcn::Template::C_PARTIAL && i < nof_base_comps);
6191 self_ref |= u.seof.ofType->chk_this_template_generic(t_comp,
6192 (embedded_modified ? INCOMPLETE_ALLOWED : INCOMPLETE_NOT_ALLOWED),
6193 OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, lhs);
6194 break;
6195 }
6196 }
6197 break; }
6198 case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
6199 map<Int, Int> index_map;
6200 for (size_t i = 0; i < t->get_nof_comps(); i++) {
6201 Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
6202 Value *index_value = (it->get_index()).get_val();
6203 // The index value must be Type::EXPECTED_DYNAMIC_VALUE integer, but
6204 // it's not required to be known at compile time.
6205 index_value->chk_expr_int(Type::EXPECTED_DYNAMIC_VALUE);
6206 Template *it_comp = it->get_template();
6207 Error_Context cntxt(it_comp, "In component %lu",
6208 (unsigned long)(i + 1));
6209 if (index_value->get_value_refd_last()->get_valuetype() == Value::V_INT) {
6210 const int_val_t *index_int = index_value->get_value_refd_last()
6211 ->get_val_Int();
6212 if (*index_int > INT_MAX) {
6213 index_value->error("An integer value less than `%d' was expected "
6214 "for indexing type `%s' instead of `%s'", INT_MAX,
6215 get_typename().c_str(), (index_int->t_str()).c_str());
6216 index_value->set_valuetype(Value::V_ERROR);
6217 } else {
6218 Int index = index_int->get_val();
6219 if (index < 0) {
6220 index_value->error("A non-negative integer value was expected "
6221 "for indexing type `%s' instead of `%s'",
6222 get_typename().c_str(), Int2string(index).c_str());
6223 index_value->set_valuetype(Value::V_ERROR);
6224 } else if (index_map.has_key(index)) {
6225 index_value->error("Duplicate index value `%s' for components "
6226 "`%s' and `%s'", Int2string(index).c_str(),
6227 Int2string((Int)i + 1).c_str(),
6228 Int2string(*index_map[index]).c_str());
6229 index_value->set_valuetype(Value::V_ERROR);
6230 } else {
6231 index_map.add(index, new Int((Int)i + 1));
6232 }
6233 }
6234 }
6235 it_comp->set_my_governor(u.seof.ofType);
6236 u.seof.ofType->chk_this_template_ref(it_comp);
6237 self_ref |= u.seof.ofType->chk_this_template_generic(it_comp,
6238 INCOMPLETE_ALLOWED, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED,
6239 SUB_CHK, implicit_omit, lhs);
6240 }
6241 for (size_t i = 0; i < index_map.size(); i++)
6242 delete index_map.get_nth_elem(i);
6243 index_map.clear();
6244 break; }
6245 default:
6246 t->error("%s cannot be used for `record of' type `%s'",
6247 t->get_templatetype_str(), get_typename().c_str());
6248 break;
6249 }
6250 return self_ref;
6251 }
6252
6253 bool Type::chk_this_template_SetOf(Template *t, namedbool is_modified,
6254 namedbool implicit_omit, Common::Assignment *lhs)
6255 {
6256 bool self_ref = false;
6257 Ttcn::Template::templatetype_t temptype = t->get_templatetype();
6258 switch (temptype) {
6259 case Ttcn::Template::OMIT_VALUE:
6260 if(t->get_length_restriction())
6261 t->warning("Redundant usage of length restriction with `omit'");
6262 break;
6263 case Ttcn::Template::SUPERSET_MATCH:
6264 case Ttcn::Template::SUBSET_MATCH: {
6265 const char *settype = temptype == Ttcn::Template::SUPERSET_MATCH ?
6266 "superset" : "subset";
6267 size_t nof_comps = t->get_nof_comps();
6268 for (size_t i = 0; i < nof_comps; i++) {
6269 Template *t_comp = t->get_temp_byIndex(i);
6270 Error_Context cntxt(t_comp, "In element %lu of %s",
6271 (unsigned long) (i + 1), settype);
6272 t_comp->set_my_governor(u.seof.ofType);
6273 u.seof.ofType->chk_this_template_ref(t_comp);
6274 // the elements of sets must be always complete
6275 self_ref |= u.seof.ofType->chk_this_template_generic(t_comp,
6276 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED,
6277 SUB_CHK, implicit_omit, lhs);
6278 if (t_comp->get_template_refd_last()->get_templatetype() ==
6279 Ttcn::Template::ANY_OR_OMIT) {
6280 if (temptype == Ttcn::Template::SUPERSET_MATCH)
6281 t_comp->warning("`*' in superset has no effect during matching");
6282 else t_comp->warning("`*' in subset. This template will match "
6283 "everything");
6284 }
6285 }
6286 break;}
6287 case Ttcn::Template::TEMPLATE_LIST: {
6288 Ttcn::Template::completeness_t c =
6289 t->get_completeness_condition_seof(is_modified);
6290 Template *t_base;
6291 size_t nof_base_comps;
6292 if (c == Ttcn::Template::C_PARTIAL) {
6293 t_base = t->get_base_template()->get_template_refd_last();
6294 // it is sure that t_base is a TEMPLATE_LIST
6295 nof_base_comps = t_base->get_nof_comps();
6296 } else {
6297 t_base = 0;
6298 nof_base_comps = 0;
6299 }
6300 size_t nof_comps = t->get_nof_comps();
6301 for(size_t i = 0; i < nof_comps; i++) {
6302 Template *t_comp = t->get_temp_byIndex(i);
6303 Error_Context cntxt(t_comp, "In component %lu", (unsigned long)(i+1));
6304 t_comp->set_my_governor(u.seof.ofType);
6305 if (t_base && i < nof_base_comps)
6306 t_comp->set_base_template(t_base->get_temp_byIndex(i));
6307 u.seof.ofType->chk_this_template_ref(t_comp);
6308 switch (t_comp->get_templatetype()) {
6309 case Ttcn::Template::PERMUTATION_MATCH:
6310 t_comp->error("%s cannot be used for `set of' type `%s'",
6311 t_comp->get_templatetype_str(), get_typename().c_str());
6312 break;
6313 case Ttcn::Template::TEMPLATE_NOTUSED:
6314 if (c == Ttcn::Template::C_MUST_COMPLETE) {
6315 t_comp->error("Not used symbol `-' is not allowed in this context");
6316 } else if (c == Ttcn::Template::C_PARTIAL && i >= nof_base_comps) {
6317 t_comp->error("Not used symbol `-' cannot be used here because "
6318 "there is no corresponding element in the base template");
6319 }
6320 break;
6321 default:
6322 bool embedded_modified = (c == Ttcn::Template::C_MAY_INCOMPLETE) ||
6323 (c == Ttcn::Template::C_PARTIAL && i < nof_base_comps);
6324 self_ref |= u.seof.ofType->chk_this_template_generic(t_comp,
6325 (embedded_modified ? INCOMPLETE_ALLOWED : INCOMPLETE_NOT_ALLOWED),
6326 OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, lhs);
6327 break;
6328 }
6329 }
6330 break; }
6331 case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
6332 map<Int, Int> index_map;
6333 for (size_t i = 0; i < t->get_nof_comps(); i++) {
6334 Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
6335 Value *index_value = (it->get_index()).get_val();
6336 index_value->chk_expr_int(Type::EXPECTED_DYNAMIC_VALUE);
6337 Template *it_comp = it->get_template();
6338 Error_Context cntxt(it_comp, "In component %lu",
6339 (unsigned long)(i + 1));
6340 if (index_value->get_value_refd_last()->get_valuetype() == Value::V_INT) {
6341 const int_val_t *index_int = index_value->get_value_refd_last()
6342 ->get_val_Int();
6343 if (*index_int > INT_MAX) {
6344 index_value->error("An integer value less than `%d' was expected "
6345 "for indexing type `%s' instead of `%s'", INT_MAX,
6346 get_typename().c_str(), (index_int->t_str()).c_str());
6347 index_value->set_valuetype(Value::V_ERROR);
6348 } else {
6349 Int index = index_int->get_val();
6350 if (index < 0) {
6351 index_value->error("A non-negative integer value was expected "
6352 "for indexing type `%s' instead of `%s'",
6353 get_typename().c_str(), Int2string(index).c_str());
6354 index_value->set_valuetype(Value::V_ERROR);
6355 } else if (index_map.has_key(index)) {
6356 index_value->error("Duplicate index value `%s' for components "
6357 "`%s' and `%s'", Int2string(index).c_str(),
6358 Int2string((Int)i + 1).c_str(),
6359 Int2string(*index_map[index]).c_str());
6360 index_value->set_valuetype(Value::V_ERROR);
6361 } else {
6362 index_map.add(index, new Int((Int)i + 1));
6363 }
6364 }
6365 }
6366 it_comp->set_my_governor(u.seof.ofType);
6367 u.seof.ofType->chk_this_template_ref(it_comp);
6368 self_ref |= u.seof.ofType->chk_this_template_generic(it_comp,
6369 INCOMPLETE_ALLOWED, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED,
6370 SUB_CHK, implicit_omit, lhs);
6371 }
6372 for (size_t i = 0; i < index_map.size(); i++)
6373 delete index_map.get_nth_elem(i);
6374 index_map.clear();
6375 break; }
6376 default:
6377 t->error("%s cannot be used for `set of' type `%s'",
6378 t->get_templatetype_str(), get_typename().c_str());
6379 break;
6380 }
6381 return self_ref;
6382 }
6383
6384 bool Type::chk_this_template_array(Template *t, namedbool is_modified,
6385 namedbool implicit_omit, Common::Assignment *lhs)
6386 {
6387 bool self_ref = false;
6388 switch (t->get_templatetype()) {
6389 case Ttcn::Template::OMIT_VALUE:
6390 if (t->get_length_restriction())
6391 t->warning("Redundant usage of length restriction with `omit'");
6392 break;
6393 case Ttcn::Template::PERMUTATION_MATCH: {
6394 size_t nof_comps = t->get_nof_comps();
6395 for (size_t i = 0; i < nof_comps; i++) {
6396 Template *t_comp = t->get_temp_byIndex(i);
6397 Error_Context cntxt(t_comp, "In element %lu of permutation",
6398 (unsigned long) (i + 1));
6399 t_comp->set_my_governor(u.array.element_type);
6400 u.array.element_type->chk_this_template_ref(t_comp);
6401 // the elements of permutation must be always complete
6402 self_ref |= u.array.element_type->chk_this_template_generic(t_comp,
6403 INCOMPLETE_NOT_ALLOWED, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
6404 NOT_IMPLICIT_OMIT, lhs);
6405 }
6406 break; }
6407 case Ttcn::Template::TEMPLATE_LIST: {
6408 Template *t_base = t->get_base_template();
6409 size_t nof_base_comps = 0;
6410 if (t_base) {
6411 t_base = t_base->get_template_refd_last();
6412 if (t_base->get_templatetype() == Ttcn::Template::TEMPLATE_LIST)
6413 nof_base_comps = t_base->get_nof_comps();
6414 else t_base = 0; // error recovery
6415 }
6416 if (!u.array.dimension->get_has_error()) {
6417 size_t array_size = u.array.dimension->get_size();
6418 size_t template_size = t->get_nof_listitems();
6419 if (array_size != template_size) {
6420 if (t->is_flattened()){
6421 t->error("Too %s elements in the array template: %lu was expected "
6422 "instead of %lu",
6423 array_size > template_size ? "few" : "many",
6424 (unsigned long)array_size, (unsigned long)template_size);
6425 }
6426 else {
6427 t->warning("The size of template cannot be resolved "
6428 "so it could not be compared to the array size");
6429 }
6430 }
6431 }
6432 size_t nof_comps = t->get_nof_comps();
6433 for (size_t i = 0; i < nof_comps; i++) {
6434 Template *t_comp = t->get_temp_byIndex(i);
6435 Error_Context cntxt(t_comp, "In array element %lu",
6436 (unsigned long)(i + 1));
6437 t_comp->set_my_governor(u.array.element_type);
6438 if (t_base && i < nof_base_comps)
6439 t_comp->set_base_template(t_base->get_temp_byIndex(i));
6440 u.array.element_type->chk_this_template_ref(t_comp);
6441 switch (t_comp->get_templatetype()) {
6442 case Ttcn::Template::PERMUTATION_MATCH:
6443 // the elements of permutation has to be checked by u.seof.ofType
6444 // the templates within the permutation always have to be complete
6445 self_ref |= chk_this_template_generic(t_comp, INCOMPLETE_NOT_ALLOWED,
6446 OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK,
6447 implicit_omit, lhs);
6448 break;
6449 case Ttcn::Template::TEMPLATE_NOTUSED:
6450 if (!is_modified)
6451 t_comp->error("Not used symbol `-' is not allowed in this "
6452 "context");
6453 break;
6454 default:
6455 self_ref |= u.array.element_type->chk_this_template_generic(t_comp,
6456 is_modified, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, lhs);
6457 break;
6458 }
6459 }
6460 break; }
6461 case Ttcn::Template::INDEXED_TEMPLATE_LIST: {
6462 map<Int, Int> index_map;
6463 for (size_t i = 0; i < t->get_nof_comps(); i++) {
6464 Ttcn::IndexedTemplate *it = t->get_indexedtemp_byIndex(i);
6465 Value *index_value = (it->get_index()).get_val();
6466 u.array.dimension->chk_index(index_value,
6467 Type::EXPECTED_DYNAMIC_VALUE);
6468 Template *it_comp = it->get_template();
6469 Error_Context cntxt(it_comp, "In component %lu",
6470 (unsigned long)(i + 1));
6471 if (index_value->get_value_refd_last()
6472 ->get_valuetype() == Value::V_INT) {
6473 const int_val_t *index_int = index_value->get_value_refd_last()
6474 ->get_val_Int();
6475 if (*index_int > INT_MAX) {
6476 index_value->error("An integer value less than `%d' was expected "
6477 "for indexing type `%s' instead of `%s'",
6478 INT_MAX, get_typename().c_str(),
6479 (index_int->t_str()).c_str());
6480 index_value->set_valuetype(Value::V_ERROR);
6481 } else {
6482 Int index = index_int->get_val();
6483 if (index_map.has_key(index)) {
6484 index_value->error("Duplicate index value `%s' for components "
6485 "`%s' and `%s'", Int2string(index).c_str(),
6486 Int2string((Int)i + 1).c_str(),
6487 Int2string(*index_map[index]).c_str());
6488 index_value->set_valuetype(Value::V_ERROR);
6489 } else {
6490 index_map.add(index, new Int((Int)i + 1));
6491 }
6492 }
6493 }
6494 it_comp->set_my_governor(u.array.element_type);
6495 u.array.element_type->chk_this_template_ref(it_comp);
6496 self_ref |= u.array.element_type->chk_this_template_generic(it_comp,
6497 is_modified, OMIT_NOT_ALLOWED, ANY_OR_OMIT_ALLOWED, SUB_CHK, implicit_omit, lhs);
6498 }
6499 for (size_t i = 0; i < index_map.size(); i++)
6500 delete index_map.get_nth_elem(i);
6501 index_map.clear();
6502 break; }
6503 default:
6504 t->error("%s cannot be used for array type `%s'",
6505 t->get_templatetype_str(), get_typename().c_str());
6506 break;
6507 }
6508 return self_ref;
6509 }
6510
6511 void Type::chk_this_template_Fat(Template *t)
6512 {
6513 t->error("%s cannot be used for type `%s'",t->get_templatetype_str(),
6514 get_typename().c_str());
6515 if(t->get_length_restriction()) t->error("Length restriction is not "
6516 "allowed for type `%s'", get_typename().c_str());
6517 }
6518
6519 void Type::chk_this_template_Signature(Template *t, namedbool is_modified)
6520 {
6521 bool self_ref = false;
6522 size_t n_type_params = get_nof_comps();
6523 switch (t->get_templatetype()) {
6524 case Ttcn::Template::TEMPLATE_LIST:
6525 // conversion: value list -> assignment notation
6526 t->set_templatetype(Ttcn::Template::NAMED_TEMPLATE_LIST);
6527 // no break
6528 case Ttcn::Template::NAMED_TEMPLATE_LIST: {
6529 map<string, Ttcn::NamedTemplate> comp_map;
6530 // it is set to false if we have lost the ordering
6531 bool in_synch = true;
6532 size_t n_template_comps = t->get_nof_comps();
6533 size_t t_i = 0;
6534 for (size_t v_i = 0; v_i < n_template_comps; v_i++) {
6535 Ttcn::NamedTemplate *nt = t->get_namedtemp_byIndex(v_i);
6536 const Identifier& temp_id = nt->get_name();
6537 const string& temp_name = temp_id.get_name();
6538 const char *temp_dispname_str = temp_id.get_dispname().c_str();
6539 if (!has_comp_withName(temp_id)) {
6540 nt->error("Reference to non-existent parameter `%s' in template "
6541 "for signature `%s'", temp_dispname_str, get_typename().c_str());
6542 in_synch = false;
6543 continue;
6544 } else if (comp_map.has_key(temp_name)) {
6545 nt->error("Duplicate parameter `%s' in template for signature `%s'",
6546 temp_dispname_str, get_typename().c_str());
6547 comp_map[temp_name]->note("Parameter `%s' is already given here",
6548 temp_dispname_str);
6549 in_synch = false;
6550 } else comp_map.add(temp_name, nt);
6551 const SignatureParam *par =
6552 u.signature.parameters->get_param_byName(temp_id);
6553 if (in_synch) {
6554 SignatureParam *par2 = 0;
6555 for ( ; t_i < n_type_params; t_i++) {
6556 par2 = u.signature.parameters->get_param_byIndex(t_i);
6557 if (par2 == par) break;
6558 }
6559 if (par2 != par) {
6560 nt->error("Unexpected parameter `%s' in signature template",
6561 temp_dispname_str);
6562 in_synch = false;
6563 } else t_i++;
6564 }
6565 Type *type = par->get_type();
6566 Template *comp_t = nt->get_template();
6567 Error_Context cntxt(comp_t, "In template for signature parameter `%s'",
6568 temp_dispname_str);
6569 comp_t->set_my_governor(type);
6570 type->chk_this_template_ref(comp_t);
6571 self_ref |= type->chk_this_template_generic(comp_t, is_modified, OMIT_NOT_ALLOWED, ANY_OR_OMIT_NOT_ALLOWED,
6572 SUB_CHK, NOT_IMPLICIT_OMIT, NULL);
6573 }
6574 if(!is_modified) {
6575 SignatureParam *first_undef_in = NULL,
6576 *first_undef_out = NULL;
6577 for (size_t i = 0; i < n_type_params; i++) {
6578 SignatureParam *par = u.signature.parameters->get_param_byIndex(i);
6579 const Identifier& id = par->get_id();
6580 if (!comp_map.has_key(id.get_name()) ||
6581 comp_map[id.get_name()]->get_template()->get_templatetype() ==
6582 Template::TEMPLATE_NOTUSED) {
6583 switch(par->get_direction()) {
6584 case SignatureParam::PARAM_IN:
6585 if(!first_undef_in) first_undef_in = par;
6586 break;
6587 case SignatureParam::PARAM_OUT:
6588 if(!first_undef_out) first_undef_out = par;
6589 break;
6590 default: //inout
6591 t->error("Signature template is incomplete, because the inout "
6592 "parameter `%s' is missing", id.get_dispname().c_str());
6593 }
6594 }
6595 }
6596 if(first_undef_in!=NULL && first_undef_out!=NULL)
6597 t->error("Signature template is incomplete, because the in parameter "
6598 "`%s' and the out parameter `%s' is missing",
6599 first_undef_in->get_id().get_dispname().c_str(),
6600 first_undef_out->get_id().get_dispname().c_str());
6601 }
6602 comp_map.clear();
6603 break;}
6604 default:
6605 t->error("%s cannot be used for signature `%s'",
6606 t->get_templatetype_str(), get_typename().c_str());
6607 break;
6608 }
6609 if (t->get_length_restriction())
6610 t->error("Length restriction is not allowed in a template for "
6611 "signature `%s'", get_typename().c_str());
6612 }
6613
6614 } // namespace Common
This page took 0.175132 seconds and 5 git commands to generate.