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