1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "../common/dbgnew.hh"
11 #include "Typestuff.hh" // FIXME CTs
12 #include "CompType.hh"
13 #include "TypeCompat.hh"
14 #include "CompField.hh"
15 #include "SigParam.hh"
16 #include "EnumItem.hh"
18 #include "Valuestuff.hh"
19 #include "ttcn3/ArrayDimensions.hh"
20 #include "asn1/Tag.hh"
21 #include "asn1/Block.hh"
22 #include "asn1/Ref.hh"
23 #include "Constraint.hh"
25 #include "../common/pattern.hh"
26 #include "ttcn3/Attributes.hh"
27 #include "XerAttributes.hh"
28 #include "ttcn3/Ttcnstuff.hh"
29 #include "ttcn3/TtcnTemplate.hh"
30 #include "ttcn3/Templatestuff.hh"
32 #include "../common/static_check.h"
33 #include "PredefFunc.hh"
35 // implemented in coding_attrib_p.y
36 extern Ttcn::ExtensionAttributes
* parse_extattributes(
37 Ttcn::WithAttribPath
*w_attrib_path
);
41 using Ttcn::MultiWithAttrib
;
42 using Ttcn::SingleWithAttrib
;
43 using Ttcn::WithAttribPath
;
45 const char* Type::type_as_string
[] = {
46 "undefined", // T_UNDEF
47 "erroneous", // T_ERROR
48 "null(ASN)", // T_NULL
51 "integer(ASN.1)", // T_INT_A
52 "real/float", // T_REAL
53 "enumerated(ASN.1)", // T_ENUM_A
54 "enumerated(TTCN-3)", // T_ENUM_T
55 "bitstring", // T_BSTR
56 "bitstring(ASN)", // T_BSTR_A
57 "hexstring(TTCN-3)", // T_HSTR
58 "octetstring", // T_OSTR
59 "charstring (TTCN-3)", // T_CSTR
60 "universal charstring(TTCN-3)", // T_USTR
61 "UTF8String(ASN.1)", // T_UTF8STRING
62 "NumericString(ASN.1)", // T_NUMERICSTRING
63 "PrintableString(ASN.1)", // T_PRINTABLESTRING
64 "TeletexString(ASN.1)", //T_TELETEXSTRING
65 "VideotexString(ASN.1)", // T_VIDEOTEXSTRING
66 "IA5String(ASN.1)", // T_IA5STRING
67 "GraphicString(ASN.1)", // T_GRAPHICSTRING,
68 "VisibleString(ASN.1)", // T_VISIBLESTRING
69 "GeneralString (ASN.1)", // T_GENERALSTRING
70 "UniversalString (ASN.1)", // T_UNIVERSALSTRING
71 "BMPString (ASN.1)", // T_BMPSTRING
72 "UnrestrictedCharacterString(ASN.1)", // T_UNRESTRICTEDSTRING
73 "UTCTime(ASN.1)", // T_UTCTIME
74 "GeneralizedTime(ASN.1)", // T_GENERALIZEDTIME
75 "Object descriptor, a kind of string (ASN.1)", // T_OBJECTDESCRIPTOR
76 "object identifier", // T_OID
77 "relative OID(ASN.1)", // T_ROID
78 "choice(ASN-1)", // T_CHOICE_A
79 "union(TTCN-3)", // T_CHOICE_T
80 "sequence (record) of", // T_SEQOF
82 "sequence(ASN-1)", // T_SEQ_A
83 "record(TTCN-3)", // T_SEQ_T
84 "set(ASN.1)", // T_SET_A
85 "set(TTCN-3)", // T_SET_T
86 "ObjectClassFieldType(ASN.1)", // T_OCFT
87 "open type(ASN.1)", // T_OPENTYPE
88 "ANY(deprecated ASN.1)", // T_ANY
89 "external(ASN.1)", // T_EXTERNAL
90 "embedded PDV(ASN.1)", // T_EMBEDDED_PDV
91 "referenced", // T_REFD
92 "special referenced(by pointer, not by name)", // T_REFDSPEC
93 "selection type(ASN.1)", // T_SELTYPE
94 "verdict type(TTCN-3)", // T_VERDICT
95 "port type(TTCN-3)", // T_PORT
96 "component type(TTCN-3)", // T_COMPONENT
97 "address type(TTCN-3)", // T_ADDRESS
98 "default type (TTCN-3)", // T_DEFAULT
99 "array(TTCN-3)", // T_ARRAY
100 "signature(TTCN-3)", // T_SIGNATURE
101 "function reference(TTCN-3)", // T_FUNCTION
102 "altstep reference(TTCN-3)", // T_ALTSTEP
103 "testcase reference(TTCN-3)", // T_TESTCASE
104 "anytype(TTCN-3)", // T_ANYTYPE
107 // =================================
109 // =================================
110 const char* Type::asString() const {
111 if (this->get_typetype() < Type::T_LAST
&& Type::T_UNDEF
< this->get_typetype()) {
112 return type_as_string
[this->get_typetype()];
115 return type_as_string
[Type::T_UNDEF
];
119 const char* Type::asString(Type::typetype_t type
) {
120 if (type
< Type::T_LAST
&& Type::T_UNDEF
< type
) {
121 return type_as_string
[type
];
124 return type_as_string
[Type::T_UNDEF
];
128 // Used by dump() for user-readable messages, by Def_ExtFunction::generate_*
129 // The text returned must match the case label without the "CT_" !
130 const char *Type::get_encoding_name(MessageEncodingType_t encoding_type
)
132 ENSURE_EQUAL(Type::T_UNDEF
, 0);
133 ENSURE_EQUAL(Type::OT_UNKNOWN
, 0);
134 switch (encoding_type
) {
148 return "<unknown encoding>";
152 Type
*Type::get_stream_type(MessageEncodingType_t encoding_type
)
154 switch (encoding_type
) {
158 case CT_XER
: // UTF-8 doesn't fit into charstring and universal is wasteful
160 return get_pooltype(T_OSTR
);
162 return get_pooltype(T_CSTR
);
164 FATAL_ERROR("Type::get_stream_type()");
169 map
<Type::typetype_t
, Type
> *Type::pooltypes
= 0;
171 Type
* Type::get_pooltype(typetype_t p_typetype
)
173 p_typetype
=get_typetype_ttcn3(p_typetype
);
189 break; // we have a pool type
191 return 0; // no pool type for you!
193 if (!pooltypes
) pooltypes
= new map
<typetype_t
, Type
>; // lazy init
194 else if (pooltypes
->has_key(p_typetype
)) return (*pooltypes
)[p_typetype
];
196 if (p_typetype
== T_COMPONENT
)
197 t
= new Type(T_COMPONENT
, new ComponentTypeBody());
198 else t
= new Type(p_typetype
);
199 t
->ownertype
= OT_POOL
;
200 pooltypes
->add(p_typetype
, t
);
204 void Type::destroy_pooltypes()
207 for(size_t i
=0; i
<pooltypes
->size(); i
++)
208 delete pooltypes
->get_nth_elem(i
);
215 Tag
*Type::get_default_tag()
217 typetype_t t_typetype
;
220 t_typetype
= T_INT_A
;
223 t_typetype
= T_BSTR_A
;
226 t_typetype
= T_ENUM_A
;
230 t_typetype
= T_SEQ_A
;
234 t_typetype
= T_SET_A
;
243 return get_type_refd()->get_tag();
245 t_typetype
= typetype
;
248 if (!default_tags
) default_tags
= new map
<typetype_t
, Tag
>;
249 else if (default_tags
->has_key(t_typetype
))
250 return (*default_tags
)[t_typetype
];
252 switch (t_typetype
) {
254 tag
= new Tag(Tag::TAG_EXPLICIT
, Tag::TAG_ALL
, (Int
)0);
257 tag
= new Tag(Tag::TAG_EXPLICIT
, Tag::TAG_ERROR
, (Int
)0);
260 int tagnumber
= get_default_tagnumber(t_typetype
);
261 if (tagnumber
< 0) FATAL_ERROR ("Type::get_default_tag():type `%s' "
262 "does not have default tag", get_typename().c_str());
263 tag
= new Tag(Tag::TAG_EXPLICIT
, Tag::TAG_UNIVERSAL
, Int(tagnumber
));
266 default_tags
->add(t_typetype
, tag
);
270 int Type::get_default_tagnumber(typetype_t p_tt
)
273 // note: tag number 0 is reserved for internal use
286 case T_OBJECTDESCRIPTOR
:
300 // note: tag numbers 14 and 15 are reserved for future use
305 case T_NUMERICSTRING
:
307 case T_PRINTABLESTRING
:
309 case T_TELETEXSTRING
:
311 case T_VIDEOTEXSTRING
:
317 case T_GENERALIZEDTIME
:
319 case T_GRAPHICSTRING
:
321 case T_VISIBLESTRING
:
323 case T_GENERALSTRING
:
325 case T_UNIVERSALSTRING
:
327 case T_UNRESTRICTEDSTRING
:
336 map
<Type::typetype_t
, Tag
> *Type::default_tags
= 0;
338 void Type::destroy_default_tags()
341 size_t nof_tags
= default_tags
->size();
342 for (size_t i
= 0; i
< nof_tags
; i
++)
343 delete default_tags
->get_nth_elem(i
);
344 default_tags
->clear();
350 Type::Type(const Type
& p
)
351 : Governor(p
), typetype(p
.typetype
)
354 if (p
.w_attrib_path
!= NULL
) FATAL_ERROR("Type::Type()");
355 tags
=p
.tags
?p
.tags
->clone():0;
357 constraints
=p
.constraints
->clone();
358 constraints
->set_my_type(this);
361 if(p
.parsed_restr
!=NULL
) {
362 parsed_restr
=new vector
<SubTypeParse
>;
363 for(size_t i
=0;i
<p
.parsed_restr
->size();i
++) {
364 SubTypeParse
*stp
= 0;
365 switch((*p
.parsed_restr
)[i
]->get_selection()) {
366 case SubTypeParse::STP_SINGLE
:
367 stp
=new SubTypeParse((*p
.parsed_restr
)[i
]->Single());
369 case SubTypeParse::STP_RANGE
:
370 stp
=new SubTypeParse((*p
.parsed_restr
)[i
]->Min(),
371 (*p
.parsed_restr
)[i
]->MinExclusive(),
372 (*p
.parsed_restr
)[i
]->Max(),
373 (*p
.parsed_restr
)[i
]->MaxExclusive());
375 case SubTypeParse::STP_LENGTH
:
376 FATAL_ERROR("Type::Type(Type&): STP_LENGTH");
378 default: FATAL_ERROR("Type::Type()");
380 parsed_restr
->add(stp
);
396 case T_NUMERICSTRING
:
397 case T_PRINTABLESTRING
:
398 case T_TELETEXSTRING
:
399 case T_VIDEOTEXSTRING
:
401 case T_GRAPHICSTRING
:
402 case T_VISIBLESTRING
:
403 case T_GENERALSTRING
:
404 case T_UNIVERSALSTRING
:
407 case T_GENERALIZEDTIME
:
408 case T_OBJECTDESCRIPTOR
:
414 case T_UNRESTRICTEDSTRING
:
420 u
.namednums
.block
=p
.u
.namednums
.block
?p
.u
.namednums
.block
->clone():0;
421 u
.namednums
.nvs
=p
.u
.namednums
.nvs
?p
.u
.namednums
.nvs
->clone():0;
424 u
.enums
.block
=p
.u
.enums
.block
?p
.u
.enums
.block
->clone():0;
425 u
.enums
.eis1
=p
.u
.enums
.eis1
?p
.u
.enums
.eis1
->clone():0;
426 u
.enums
.ellipsis
=p
.u
.enums
.ellipsis
;
427 u
.enums
.excSpec
=p
.u
.enums
.excSpec
?p
.u
.enums
.excSpec
->clone():0;
428 u
.enums
.eis2
=p
.u
.enums
.eis2
?p
.u
.enums
.eis2
->clone():0;
431 u
.enums
.eis
=p
.u
.enums
.eis
->clone();
432 u
.enums
.eis_by_name
=0;
438 u
.secho
.cfm
=p
.u
.secho
.cfm
->clone();
439 u
.secho
.field_by_name
= 0;
440 u
.secho
.component_internal
= false;
441 u
.secho
.has_single_charenc
= false;
445 u
.secho
.tr_compsof_ready
=p
.u
.secho
.tr_compsof_ready
;
449 u
.secho
.block
=p
.u
.secho
.block
?p
.u
.secho
.block
->clone():0;
450 u
.secho
.ctss
=p
.u
.secho
.ctss
?p
.u
.secho
.ctss
->clone():0;
451 u
.secho
.field_by_name
= 0;
452 u
.secho
.component_internal
= false;
453 u
.secho
.has_single_charenc
= false;
457 u
.seof
.ofType
=p
.u
.seof
.ofType
->clone();
458 u
.seof
.component_internal
= false;
461 u
.ref
.ref
=p
.u
.ref
.ref
->clone();
463 u
.ref
.component_internal
= false;
466 u
.ref
.oc_defn
=p
.u
.ref
.oc_defn
;
467 u
.ref
.oc_fieldname
=p
.u
.ref
.oc_fieldname
;
470 u
.ref
.type_refd
=p
.u
.ref
.type_refd
;
471 u
.ref
.component_internal
= false;
474 u
.seltype
.id
=p
.u
.seltype
.id
->clone();
475 u
.seltype
.type
=p
.u
.seltype
.type
->clone();
476 u
.seltype
.type_refd
=0;
479 u
.secho
.cfm
=new CompFieldMap();
480 u
.secho
.cfm
->set_my_type(this);
481 u
.secho
.oc_defn
=p
.u
.secho
.oc_defn
;
482 u
.secho
.oc_fieldname
=p
.u
.secho
.oc_fieldname
;
483 u
.secho
.my_tableconstraint
=0;
484 u
.secho
.field_by_name
= 0;
485 u
.secho
.component_internal
= false;
486 u
.secho
.has_single_charenc
= false;
489 u
.array
.element_type
=p
.u
.array
.element_type
->clone();
490 u
.array
.dimension
= p
.u
.array
.dimension
->clone();
491 u
.array
.in_typedef
= p
.u
.array
.in_typedef
;
492 u
.array
.component_internal
= false;
495 u
.port
= p
.u
.port
->clone();
498 u
.component
= p
.u
.component
->clone();
504 u
.signature
.parameters
= p
.u
.signature
.parameters
?
505 p
.u
.signature
.parameters
->clone() : 0;
506 u
.signature
.return_type
= p
.u
.signature
.return_type
?
507 p
.u
.signature
.return_type
->clone() : 0;
508 u
.signature
.no_block
= p
.u
.signature
.no_block
;
509 u
.signature
.exceptions
= p
.u
.signature
.exceptions
?
510 p
.u
.signature
.exceptions
->clone() : 0;
511 u
.signature
.component_internal
= false;
515 u
.fatref
.fp_list
= p
.u
.fatref
.fp_list
->clone();
516 u
.fatref
.runs_on
.ref
= p
.u
.fatref
.runs_on
.ref
?
517 p
.u
.fatref
.runs_on
.ref
->clone() : 0;
518 u
.fatref
.runs_on
.self
= p
.u
.fatref
.runs_on
.self
;
519 u
.fatref
.runs_on
.type
= 0;
520 u
.fatref
.return_type
= p
.u
.fatref
.return_type
?
521 p
.u
.fatref
.return_type
->clone() : 0;
522 u
.fatref
.is_startable
= false;
523 u
.fatref
.returns_template
= p
.u
.fatref
.returns_template
;
524 u
.fatref
.template_restriction
= p
.u
.fatref
.template_restriction
;
527 u
.fatref
.fp_list
= p
.u
.fatref
.fp_list
->clone();
528 u
.fatref
.runs_on
.ref
= p
.u
.fatref
.runs_on
.ref
?
529 p
.u
.fatref
.runs_on
.ref
->clone() : 0;
530 u
.fatref
.runs_on
.self
= false;
531 u
.fatref
.runs_on
.type
= 0;
532 u
.fatref
.system
.ref
= p
.u
.fatref
.system
.ref
?
533 p
.u
.fatref
.system
.ref
->clone() : 0;
534 u
.fatref
.system
.type
= 0;
535 u
.fatref
.is_startable
= false;
536 u
.fatref
.returns_template
= false;
537 u
.fatref
.template_restriction
= TR_NONE
;
540 FATAL_ERROR("Type::Type()");
546 tags_checked
= false;
547 tbl_cons_checked
= false;
548 text_checked
= false;
549 json_checked
= false;
553 raw_length_calculated
= false;
554 has_opentypes
= false;
555 opentype_outermost
= false;
556 code_generated
= false;
557 embed_values_possible
= false;
558 use_nil_possible
= false;
559 use_order_possible
= false;
565 encode_attrib_path
= 0;
573 ownertype
= OT_UNKNOWN
;
575 chk_finished
= false;
578 void Type::clean_up()
592 case T_NUMERICSTRING
:
593 case T_PRINTABLESTRING
:
594 case T_TELETEXSTRING
:
595 case T_VIDEOTEXSTRING
:
597 case T_GRAPHICSTRING
:
598 case T_VISIBLESTRING
:
599 case T_GENERALSTRING
:
600 case T_UNIVERSALSTRING
:
603 case T_GENERALIZEDTIME
:
604 case T_OBJECTDESCRIPTOR
:
610 case T_UNRESTRICTEDSTRING
:
619 delete u
.namednums
.block
;
620 delete u
.namednums
.nvs
;
623 delete u
.enums
.block
;
625 u
.enums
.eis1
->release_eis();
629 u
.enums
.eis2
->release_eis();
635 if (u
.enums
.eis_by_name
) {
636 for (size_t a
= 0; a
< u
.enums
.eis_by_name
->size(); a
++) {
637 delete u
.enums
.eis_by_name
->get_nth_elem(a
);
639 u
.enums
.eis_by_name
->clear();
640 delete u
.enums
.eis_by_name
;
646 delete u
.secho
.block
;
655 if (u
.secho
.field_by_name
) {
656 for(size_t a
= 0; a
< u
.secho
.field_by_name
->size(); a
++) {
657 delete u
.secho
.field_by_name
->get_nth_elem(a
);
659 u
.secho
.field_by_name
->clear();
660 delete u
.secho
.field_by_name
;
665 delete u
.seof
.ofType
;
672 delete u
.seltype
.type
;
675 delete u
.array
.element_type
;
676 delete u
.array
.dimension
;
685 delete u
.signature
.parameters
;
686 delete u
.signature
.return_type
;
687 delete u
.signature
.exceptions
;
691 delete u
.fatref
.fp_list
;
692 delete u
.fatref
.runs_on
.ref
;
693 delete u
.fatref
.return_type
;
696 delete u
.fatref
.fp_list
;
697 delete u
.fatref
.runs_on
.ref
;
698 delete u
.fatref
.system
.ref
;
701 FATAL_ERROR("Type::clean_up()");
721 for (size_t i
= 0; i
< parsed_restr
->size(); i
++)
722 delete (*parsed_restr
)[i
];
723 parsed_restr
->clear();
727 delete w_attrib_path
;
729 delete encode_attrib_path
;
730 encode_attrib_path
= 0;
733 Type::Type(typetype_t p_tt
)
734 : Governor(S_T
), typetype(p_tt
)
749 case T_NUMERICSTRING
:
750 case T_PRINTABLESTRING
:
751 case T_TELETEXSTRING
:
752 case T_VIDEOTEXSTRING
:
754 case T_GRAPHICSTRING
:
755 case T_VISIBLESTRING
:
756 case T_GENERALSTRING
:
757 case T_UNIVERSALSTRING
:
760 case T_GENERALIZEDTIME
:
761 case T_OBJECTDESCRIPTOR
:
767 case T_UNRESTRICTEDSTRING
:
772 u
.secho
.cfm
= new CompFieldMap
;
773 u
.secho
.cfm
->set_my_type(this);
776 u
.secho
.field_by_name
= 0;
777 u
.secho
.component_internal
= false;
778 u
.secho
.has_single_charenc
= false;
789 FATAL_ERROR("Type::Type()");
793 Type::Type(typetype_t p_tt
, EnumItems
*p_eis
)
794 : Governor(S_T
), typetype(p_tt
)
796 if (p_tt
!= T_ENUM_T
|| !p_eis
) FATAL_ERROR("Type::Type()");
799 u
.enums
.eis_by_name
=0;
802 Type::Type(typetype_t p_tt
, Block
*p_block
)
803 : Governor(S_T
), typetype(p_tt
)
805 if (!p_block
) FATAL_ERROR("NULL parameter");
810 u
.namednums
.block
=p_block
;
814 u
.enums
.eis
=new EnumItems();
815 u
.enums
.block
=p_block
;
817 u
.enums
.ellipsis
=false;
820 u
.enums
.eis_by_name
=0;
824 u
.secho
.tr_compsof_ready
=false;
828 u
.secho
.block
=p_block
;
830 u
.secho
.field_by_name
= 0;
831 u
.secho
.component_internal
= false;
832 u
.secho
.has_single_charenc
= false;
835 FATAL_ERROR("Type::Type()");
839 Type::Type(typetype_t p_tt
,
840 EnumItems
*p_eis1
, bool p_ellipsis
, EnumItems
*p_eis2
)
841 : Governor(S_T
), typetype(p_tt
)
843 if (p_tt
!= T_ENUM_A
|| !p_eis1
) FATAL_ERROR("Type::Type()");
845 u
.enums
.eis
=new EnumItems();
848 u
.enums
.ellipsis
=p_ellipsis
;
850 u
.enums
.eis_by_name
=0;
853 Type::Type(typetype_t p_tt
, CompFieldMap
*p_cfm
)
854 : Governor(S_T
), typetype(p_tt
)
856 if (!p_cfm
) FATAL_ERROR("NULL parameter");
863 u
.secho
.field_by_name
= 0;
864 u
.secho
.component_internal
= false;
865 u
.secho
.has_single_charenc
= false;
868 FATAL_ERROR("Type::Type()");
872 Type::Type(typetype_t p_tt
, Type
*p_type
)
873 : Governor(S_T
), typetype(p_tt
)
875 if (!p_type
) FATAL_ERROR("NULL parameter");
880 u
.seof
.ofType
=p_type
;
881 u
.seof
.ofType
->set_ownertype(OT_RECORD_OF
, this);
882 u
.seof
.component_internal
= false;
885 u
.ref
.type_refd
=p_type
;
886 u
.ref
.type_refd
->set_ownertype(OT_REF_SPEC
, this);
887 u
.ref
.component_internal
= false;
890 FATAL_ERROR("Type::Type()");
894 Type::Type(typetype_t p_tt
, Identifier
*p_id
, Type
*p_type
)
895 : Governor(S_T
), typetype(p_tt
)
897 if (p_tt
!= T_SELTYPE
|| !p_id
|| !p_type
) FATAL_ERROR("Type::Type()");
900 u
.seltype
.type
=p_type
;
901 u
.seltype
.type
->set_ownertype(OT_SELTYPE
, this);
902 u
.seltype
.type_refd
=0;
905 Type::Type(typetype_t p_tt
, Type
*p_type
, Ttcn::ArrayDimension
*p_dim
,
907 : Governor(S_T
), typetype(p_tt
)
909 if (p_tt
!= T_ARRAY
|| !p_type
|| !p_dim
) FATAL_ERROR("Type::Type()");
911 u
.array
.element_type
= p_type
;
912 u
.array
.element_type
->set_ownertype(OT_ARRAY
, this);
913 u
.array
.dimension
= p_dim
;
914 u
.array
.in_typedef
= p_in_typedef
;
915 u
.array
.component_internal
= false;
918 Type::Type(typetype_t p_tt
, Type
*p_type
, OC_defn
*p_oc_defn
,
919 const Identifier
*p_id
)
920 : Governor(S_T
), typetype(p_tt
)
922 if (p_tt
!= T_OCFT
|| !p_type
||!p_oc_defn
|| !p_id
)
923 FATAL_ERROR("Type::Type()");
925 u
.ref
.type_refd
=p_type
;
926 u
.ref
.type_refd
->set_ownertype(OT_OCFT
, this);
927 u
.ref
.oc_defn
=p_oc_defn
;
928 u
.ref
.oc_fieldname
=p_id
;
929 u
.ref
.component_internal
= false;
932 Type::Type(typetype_t p_tt
, OC_defn
*p_oc_defn
,
933 const Identifier
*p_id
)
934 : Governor(S_T
), typetype(p_tt
)
936 if (p_tt
!= T_OPENTYPE
|| !p_oc_defn
|| !p_id
) FATAL_ERROR("Type::Type()");
939 u
.secho
.cfm
=new CompFieldMap();
940 u
.secho
.cfm
->set_my_type(this);
941 u
.secho
.oc_defn
=p_oc_defn
;
942 u
.secho
.oc_fieldname
=p_id
;
943 u
.secho
.my_tableconstraint
=0;
944 u
.secho
.field_by_name
= 0;
945 u
.secho
.component_internal
= false;
946 u
.secho
.has_single_charenc
= false;
949 Type::Type(typetype_t p_tt
, Reference
*p_ref
)
950 : Governor(S_T
), typetype(p_tt
)
952 if (p_tt
!= T_REFD
|| !p_ref
) FATAL_ERROR("Type::Type()");
956 u
.ref
.component_internal
= false;
959 Type::Type(typetype_t p_tt
, Ttcn::PortTypeBody
*p_pb
)
960 : Governor(S_T
), typetype(p_tt
)
962 if (p_tt
!= T_PORT
|| !p_pb
) FATAL_ERROR("Type::Type()");
965 p_pb
->set_my_type(this);
968 Type::Type(typetype_t p_tt
, ComponentTypeBody
*p_cb
)
969 : Governor(S_T
), typetype(p_tt
)
971 if (p_tt
!= T_COMPONENT
|| !p_cb
) FATAL_ERROR("Type::Type()");
974 p_cb
->set_my_type(this);
977 Type::Type(typetype_t p_tt
, SignatureParamList
*p_params
, Type
*p_returntype
,
978 bool p_noblock
, SignatureExceptions
*p_exceptions
)
979 : Governor(S_T
), typetype(p_tt
)
981 if (p_tt
!= T_SIGNATURE
|| (p_returntype
&& p_noblock
))
982 FATAL_ERROR("Type::Type()");
984 u
.signature
.parameters
= p_params
;
985 if ((u
.signature
.return_type
= p_returntype
)) { // check assignment for 0
986 u
.signature
.return_type
->set_ownertype(OT_SIGNATURE
, this);
988 u
.signature
.no_block
= p_noblock
;
989 u
.signature
.exceptions
= p_exceptions
;
990 u
.signature
.component_internal
= false;
993 Type::Type(typetype_t p_tt
,Ttcn::FormalParList
*p_params
,
994 Ttcn::Reference
* p_runs_on_ref
, bool p_runs_on_self
,
995 Type
*p_returntype
, bool p_returns_template
,
996 template_restriction_t p_template_restriction
)
997 : Governor(S_T
), typetype(p_tt
)
999 if (p_tt
!= T_FUNCTION
|| !p_params
|| (!p_returntype
&& p_returns_template
)
1000 || (p_runs_on_ref
&& p_runs_on_self
)) FATAL_ERROR("Type::Type()");
1002 u
.fatref
.fp_list
= p_params
;
1003 u
.fatref
.runs_on
.ref
= p_runs_on_ref
;
1004 u
.fatref
.runs_on
.self
= p_runs_on_self
;
1005 u
.fatref
.runs_on
.type
= 0;
1006 if ((u
.fatref
.return_type
= p_returntype
)) { // check assignment for 0
1007 u
.fatref
.return_type
->set_ownertype(OT_FUNCTION
, this);
1009 u
.fatref
.is_startable
= false;
1010 u
.fatref
.returns_template
= p_returns_template
;
1011 u
.fatref
.template_restriction
= p_template_restriction
;
1014 Type::Type(typetype_t p_tt
,Ttcn::FormalParList
*p_params
,
1015 Ttcn::Reference
* p_runs_on_ref
, bool p_runs_on_self
)
1016 : Governor(S_T
), typetype(p_tt
)
1018 if(p_tt
!= T_ALTSTEP
|| !p_params
|| (p_runs_on_ref
&& p_runs_on_self
))
1019 FATAL_ERROR("Type::Type()");
1021 u
.fatref
.fp_list
= p_params
;
1022 u
.fatref
.runs_on
.ref
= p_runs_on_ref
;
1023 u
.fatref
.runs_on
.self
= p_runs_on_self
;
1024 u
.fatref
.runs_on
.type
= 0;
1025 u
.fatref
.return_type
= 0;
1026 u
.fatref
.is_startable
= false;
1027 u
.fatref
.returns_template
= false;
1028 u
.fatref
.template_restriction
= TR_NONE
;
1031 Type::Type(typetype_t p_tt
,Ttcn::FormalParList
*p_params
,
1032 Ttcn::Reference
* p_runs_on_ref
, Ttcn::Reference
*p_system_ref
)
1033 : Governor(S_T
), typetype(p_tt
)
1035 if(p_tt
!= T_TESTCASE
|| !p_params
|| !p_runs_on_ref
)
1036 FATAL_ERROR("Type::Type()");
1038 u
.fatref
.fp_list
= p_params
;
1039 u
.fatref
.runs_on
.ref
= p_runs_on_ref
;
1040 u
.fatref
.runs_on
.self
= false;
1041 u
.fatref
.runs_on
.type
= 0;
1042 u
.fatref
.system
.ref
= p_system_ref
;
1043 u
.fatref
.system
.type
= 0;
1044 u
.fatref
.is_startable
= false;
1045 u
.fatref
.returns_template
= false;
1046 u
.fatref
.template_restriction
= TR_NONE
;
1054 void Type::free_pools()
1056 destroy_default_tags();// Additionally: R&S license warning
1057 destroy_pooltypes();// Additionally: R&S license checkin/disconnect/shutdown
1060 Type
*Type::clone() const
1062 return new Type(*this);
1065 Type::typetype_t
Type::get_typetype_ttcn3(typetype_t p_tt
)
1076 case T_UNIVERSALSTRING
:
1078 case T_TELETEXSTRING
:
1079 case T_VIDEOTEXSTRING
:
1080 case T_GRAPHICSTRING
:
1081 case T_OBJECTDESCRIPTOR
:
1082 case T_GENERALSTRING
:
1084 case T_NUMERICSTRING
:
1085 case T_PRINTABLESTRING
:
1087 case T_VISIBLESTRING
:
1089 case T_GENERALIZEDTIME
:
1100 case T_EMBEDDED_PDV
:
1101 case T_UNRESTRICTEDSTRING
:
1107 } // switch typetype
1110 bool Type::is_asn1() const
1112 if (my_scope
) return Setting::is_asn1();
1113 // the type might be a pool type, which is considered to be a TTCN-3 type
1114 typetype_t t_typetype
= get_typetype_ttcn3(typetype
);
1115 if (pooltypes
&& pooltypes
->has_key(t_typetype
) &&
1116 (*pooltypes
)[t_typetype
] == this) return false;
1117 else FATAL_ERROR("Type::is_asn1()");
1120 bool Type::is_ref() const
1123 case T_UNRESTRICTEDSTRING
:
1126 case T_EMBEDDED_PDV
:
1137 bool Type::is_secho() const
1154 Type::truth
Type::is_charenc()
1160 bool possible
= true;
1161 size_t ncomp
= u
.secho
.cfm
->get_nof_comps();
1162 for (size_t i
=0; i
<ncomp
; ++i
) {
1163 CompField
* cf
= u
.secho
.cfm
->get_comp_byIndex(i
);
1164 if (cf
->get_type()->is_charenc() == No
) {
1165 possible
= false; break;
1169 return (xerattrib
&& (xerattrib
->useUnion_
|| xerattrib
->useType_
)) ? Yes
: No
;
1178 // UNTAGGED cannot be used to make a type character-encodable!
1179 // But USE-QNAME can!
1180 return (xerattrib
&& xerattrib
->useQName_
) ? Yes
: No
;
1182 case T_SEQOF
: // A record-of is character-encodable if it has the "list"
1183 case T_SETOF
: // attribute and its element is character-encodable.
1184 return (xerattrib
&& xerattrib
->list_
&& (u
.seof
.ofType
->is_charenc()==Yes
))
1194 truth retval
= get_type_refd_last()->is_charenc();
1195 if (retval
== Yes
) return Yes
;
1196 else if (retval
== Maybe
) {
1197 if (xerattrib
&& xerattrib
->useUnion_
) return Yes
;
1199 // else fall through to No
1209 // TODO ASN.1 restricted character string types when (if) ASN.1 gets XER
1210 // TODO check subtype; strings must be restricted to not contain
1211 // control characters (0..0x1F except 9,0x0A,0x0D)
1217 /* FIXME : this kind of check should be applied to elements of secho,
1218 * not to the type of the element ! */
1223 bool Type::has_empty_xml() {
1224 bool answer
= false;
1226 case T_SEQ_A
: case T_SEQ_T
:
1227 case T_SET_A
: case T_SET_T
: {
1228 answer
= true; // If all components are optional.
1229 size_t n_comps
= get_nof_comps();
1230 for (size_t i
= 0; i
< n_comps
; ++i
) {
1231 CompField
* cf
= get_comp_byIndex(i
);
1232 if (!cf
->get_is_optional()) {
1238 case T_SEQOF
: case T_SETOF
:
1239 // _If_ there is a length restriction, 0 length must be allowed.
1240 // By this time parsed_restr has been absorbed into sub_type.
1241 answer
= (sub_type
==0) || sub_type
->zero_length_allowed();
1249 void Type::set_fullname(const string
& p_fullname
)
1251 Governor::set_fullname(p_fullname
);
1255 if(u
.namednums
.block
) u
.namednums
.block
->set_fullname(p_fullname
);
1257 u
.namednums
.nvs
->set_fullname(p_fullname
+".<namedvalues>");
1260 if(u
.enums
.eis1
) u
.enums
.eis1
->set_fullname(p_fullname
);
1261 if(u
.enums
.eis2
) u
.enums
.eis2
->set_fullname(p_fullname
);
1264 u
.enums
.eis
->set_fullname(p_fullname
);
1271 u
.secho
.cfm
->set_fullname(p_fullname
);
1276 if (u
.secho
.ctss
) u
.secho
.ctss
->set_fullname(p_fullname
);
1280 string
subtypename(".<oftype>");
1281 Type
* t
= u
.seof
.ofType
;
1282 /* Do NOT call get_type_refd_last() or else fatal_error !
1283 * The AST is not fully set up. */
1285 /* XER will use these strings */
1286 switch (t
->typetype
)
1288 case T_EMBEDDED_PDV
: case T_EXTERNAL
:
1289 case T_SEQ_A
: case T_SEQ_T
:
1290 subtypename
= ".SEQUENCE";
1293 case T_SET_A
: case T_SET_T
:
1294 subtypename
= ".SET";
1298 subtypename
= ".SEQUENCE_OF";
1302 subtypename
= ".SET_OF";
1306 subtypename
= ".BITSTRING";
1310 subtypename
= ".BOOLEAN";
1313 case T_CHOICE_A
: case T_CHOICE_T
:
1314 subtypename
= ".CHOICE";
1317 case T_ENUM_A
: case T_ENUM_T
:
1318 subtypename
= ".ENUMERATED";
1321 case T_INT_A
: case T_INT
:
1322 subtypename
= ".INTEGER";
1328 u
.seof
.ofType
->set_fullname(p_fullname
+subtypename
);
1331 u
.ref
.ref
->set_fullname(p_fullname
);
1334 u
.seltype
.type
->set_fullname(p_fullname
+".<selection>");
1337 u
.port
->set_fullname(p_fullname
);
1340 u
.component
->set_fullname(p_fullname
);
1343 u
.array
.element_type
->set_fullname(p_fullname
+ ".<element_type>");
1344 u
.array
.dimension
->set_fullname(p_fullname
+ ".<dimension>");
1347 if (u
.signature
.parameters
)
1348 u
.signature
.parameters
->set_fullname(p_fullname
);
1349 if (u
.signature
.return_type
)
1350 u
.signature
.return_type
->set_fullname(p_fullname
+ ".<return_type>");
1351 if (u
.signature
.exceptions
)
1352 u
.signature
.exceptions
->set_fullname(p_fullname
+ ".<exception_list>");
1356 u
.fatref
.fp_list
->set_fullname(p_fullname
+ "<formal_par_list>");
1357 if (u
.fatref
.runs_on
.ref
)
1358 u
.fatref
.runs_on
.ref
->set_fullname(p_fullname
+ "<runs_on_type>");
1359 if (u
.fatref
.return_type
)
1360 u
.fatref
.return_type
->set_fullname(p_fullname
+ "<return type>");
1363 u
.fatref
.fp_list
->set_fullname(p_fullname
+ ".<formal_par_list>");
1364 if (u
.fatref
.runs_on
.ref
)
1365 u
.fatref
.runs_on
.ref
->set_fullname(p_fullname
+".<runs_on_type>");
1366 if (u
.fatref
.system
.ref
)
1367 u
.fatref
.system
.ref
->set_fullname(p_fullname
+ ".<system_type>");
1374 void Type::set_my_scope(Scope
*p_scope
)
1376 Governor::set_my_scope(p_scope
);
1377 if(tags
) tags
->set_my_scope(p_scope
);
1381 if(u
.namednums
.nvs
) u
.namednums
.nvs
->set_my_scope(p_scope
);
1384 if(u
.enums
.eis1
) u
.enums
.eis1
->set_my_scope(p_scope
);
1385 if(u
.enums
.eis2
) u
.enums
.eis2
->set_my_scope(p_scope
);
1388 u
.enums
.eis
->set_my_scope(p_scope
);
1395 u
.secho
.cfm
->set_my_scope(p_scope
);
1400 if(u
.secho
.ctss
) u
.secho
.ctss
->set_my_scope(p_scope
);
1404 u
.seof
.ofType
->set_my_scope(p_scope
);
1407 u
.ref
.ref
->set_my_scope(p_scope
);
1410 u
.seltype
.type
->set_my_scope(p_scope
);
1413 u
.array
.element_type
->set_my_scope(p_scope
);
1414 u
.array
.dimension
->set_my_scope(p_scope
);
1417 u
.port
->set_my_scope(p_scope
);
1420 if (u
.signature
.parameters
)
1421 u
.signature
.parameters
->set_my_scope(p_scope
);
1422 if (u
.signature
.return_type
)
1423 u
.signature
.return_type
->set_my_scope(p_scope
);
1424 if (u
.signature
.exceptions
)
1425 u
.signature
.exceptions
->set_my_scope(p_scope
);
1428 u
.component
->set_my_scope(p_scope
);
1432 // the scope of parameter list is set later in chk_Fat()
1433 if (u
.fatref
.runs_on
.ref
)
1434 u
.fatref
.runs_on
.ref
->set_my_scope(p_scope
);
1435 if (u
.fatref
.return_type
)
1436 u
.fatref
.return_type
->set_my_scope(p_scope
);
1439 // the scope of parameter list is set later in chk_Fat()
1440 if (u
.fatref
.runs_on
.ref
)
1441 u
.fatref
.runs_on
.ref
->set_my_scope(p_scope
);
1442 if (u
.fatref
.system
.ref
)
1443 u
.fatref
.system
.ref
->set_my_scope(p_scope
);
1450 Type
* Type::get_type_refd(ReferenceChain
*refch
)
1454 if(refch
&& !refch
->add(get_fullname())) goto error
;
1455 if(!u
.ref
.type_refd
) {
1456 Assignment
*ass
= u
.ref
.ref
->get_refd_assignment();
1457 if (!ass
) goto error
; // The referenced assignment is not found
1458 switch (ass
->get_asstype()) {
1459 case Assignment::A_ERROR
:
1461 case Assignment::A_TYPE
:
1462 case Assignment::A_VS
:
1463 u
.ref
.type_refd
= ass
->get_Type()->get_field_type(
1464 u
.ref
.ref
->get_subrefs(), EXPECTED_DYNAMIC_VALUE
, refch
);
1465 if (!u
.ref
.type_refd
) goto error
;
1467 //case Assignment::A_VS:
1468 //u.ref.type_refd = ass->get_Type();
1469 // if(!u.ref.type_refd) goto error;
1471 case Assignment::A_OC
:
1472 case Assignment::A_OBJECT
:
1473 case Assignment::A_OS
: {
1474 Setting
*setting
= u
.ref
.ref
->get_refd_setting();
1475 if (!setting
|| setting
->get_st() == Setting::S_ERROR
) goto error
;
1477 u
.ref
.type_refd
= dynamic_cast<Type
*>(setting
);
1478 if(!u
.ref
.type_refd
) {
1479 error("`%s' is not a reference to a type",
1480 u
.ref
.ref
->get_dispname().c_str());
1484 if (u
.ref
.type_refd
->ownertype
== OT_UNKNOWN
) {
1485 u
.ref
.type_refd
->set_ownertype(OT_REF
, this);
1490 error("`%s' is not a reference to a type",
1491 u
.ref
.ref
->get_dispname().c_str());
1494 if(!u
.ref
.type_refd
->get_my_scope()) {
1496 u
.ref
.type_refd
->set_my_scope(get_my_scope());
1497 u
.ref
.type_refd
->set_parent_type(get_parent_type());
1498 u
.ref
.type_refd
->set_genname(get_genname_own(), string("type"));
1499 u
.ref
.type_refd
->set_fullname(get_fullname()+".type");
1501 if (u
.ref
.type_refd
->typetype
== T_OPENTYPE
&& !constraints
)
1502 warning("An open type without table constraint is useless in TTCN-3");
1504 return u
.ref
.type_refd
;
1507 if(refch
&& !refch
->add(get_fullname())) goto error
;
1508 if(!u
.seltype
.type_refd
) {
1509 Type
*t
=u
.seltype
.type
->get_type_refd_last(refch
);
1510 if(t
->typetype
==T_ERROR
) goto error
;
1511 if(t
->typetype
!=T_CHOICE_A
) {
1512 error("(Reference to) a CHOICE type was expected"
1513 " in selection type.");
1516 if(!t
->has_comp_withName(*u
.seltype
.id
)) {
1517 error("No alternative with name `%s' in the given type `%s'.",
1518 u
.seltype
.id
->get_dispname().c_str(),
1519 t
->get_fullname().c_str());
1522 u
.seltype
.type_refd
=t
->get_comp_byName(*u
.seltype
.id
)->get_type();
1524 return u
.seltype
.type_refd
;
1528 if(refch
&& !refch
->add(get_fullname())) goto error
;
1529 return u
.ref
.type_refd
;
1532 if (!my_scope
) FATAL_ERROR("Type::get_type_refd()");
1533 Identifier
t_id(Identifier::ID_ASN
, string("EXTERNAL"));
1534 return my_scope
->get_scope_asss()->get_local_ass_byId(t_id
)->get_Type(); }
1535 case T_EMBEDDED_PDV
: {
1536 if (!my_scope
) FATAL_ERROR("Type::get_type_refd()");
1537 Identifier
t_id(Identifier::ID_ASN
, string("EMBEDDED PDV"));
1538 return my_scope
->get_scope_asss()->get_local_ass_byId(t_id
)->get_Type(); }
1539 case T_UNRESTRICTEDSTRING
: {
1540 if (!my_scope
) FATAL_ERROR("Type::get_type_refd()");
1541 Identifier
t_id(Identifier::ID_ASN
, string("CHARACTER STRING"));
1542 return my_scope
->get_scope_asss()->get_local_ass_byId(t_id
)->get_Type(); }
1544 if (refch
&& !refch
->add(get_fullname())) goto error
;
1545 if (u
.address
) return u
.address
;
1546 if (!my_scope
) FATAL_ERROR("Type::get_type_refd()");
1547 u
.address
= my_scope
->get_scope_mod()->get_address_type();
1549 error("Type `address' is not defined in this module");
1554 FATAL_ERROR("Type::get_type_refd()");
1562 Type
* Type::get_type_refd_last(ReferenceChain
*refch
)
1565 while(t
->is_ref()) t
=t
->get_type_refd(refch
);
1569 Type
*Type::get_field_type(Ttcn::FieldOrArrayRefs
*subrefs
,
1570 expected_value_t expected_index
, ReferenceChain
*refch
,
1571 bool interrupt_if_optional
)
1573 if (!subrefs
) return this;
1575 if (expected_index
== EXPECTED_TEMPLATE
)
1576 expected_index
= EXPECTED_DYNAMIC_VALUE
;
1577 size_t nof_refs
= subrefs
->get_nof_refs();
1578 subrefs
->clear_string_element_ref();
1579 for (size_t i
= 0; i
< nof_refs
; i
++) {
1580 if (refch
) refch
->mark_state();
1581 t
= t
->get_type_refd_last(refch
);
1582 if (refch
) refch
->prev_state();
1583 // stop immediately if current type t is erroneous
1584 // (e.g. because of circular reference)
1585 if (t
->typetype
== T_ERROR
) return 0;
1586 Ttcn::FieldOrArrayRef
*ref
= subrefs
->get_ref(i
);
1587 switch (ref
->get_type()) {
1588 case Ttcn::FieldOrArrayRef::FIELD_REF
: {
1589 const Identifier
& id
= *ref
->get_id();
1590 switch (t
->typetype
) {
1601 ref
->error("Invalid field reference `%s': type `%s' "
1602 "does not have fields", id
.get_dispname().c_str(),
1603 t
->get_typename().c_str());
1606 if (!t
->has_comp_withName(id
)) {
1607 ref
->error("Reference to non-existent field `%s' in type `%s'",
1608 id
.get_dispname().c_str(),
1609 t
->get_typename().c_str());
1612 CompField
* cf
= t
->get_comp_byName(id
);
1613 if (interrupt_if_optional
&& cf
->get_is_optional()) return 0;
1616 case Ttcn::FieldOrArrayRef::ARRAY_REF
: {
1617 Type
*embedded_type
= 0;
1618 switch (t
->typetype
) {
1621 embedded_type
= t
->u
.seof
.ofType
;
1624 embedded_type
= t
->u
.array
.element_type
;
1633 case T_NUMERICSTRING
:
1634 case T_PRINTABLESTRING
:
1635 case T_TELETEXSTRING
:
1636 case T_VIDEOTEXSTRING
:
1638 case T_GRAPHICSTRING
:
1639 case T_VISIBLESTRING
:
1640 case T_GENERALSTRING
:
1641 case T_UNIVERSALSTRING
:
1644 case T_GENERALIZEDTIME
:
1645 case T_OBJECTDESCRIPTOR
:
1646 if (subrefs
->refers_to_string_element()) {
1647 ref
->error("A string element of type `%s' cannot be indexed",
1648 t
->get_typename().c_str());
1651 subrefs
->set_string_element_ref();
1652 // string elements have the same type as the string itself
1657 ref
->error("Type `%s' cannot be indexed",
1658 t
->get_typename().c_str());
1661 // check the index value
1662 Value
*index_value
= ref
->get_val();
1663 if (t
->typetype
== T_ARRAY
) {
1664 // checking of array index is performed by the array dimension
1665 t
->u
.array
.dimension
->chk_index(index_value
, expected_index
);
1667 // perform a generic index check for other types
1668 if (refch
== 0 // variable assignment
1669 || index_value
->get_valuetype() != Value::V_NOTUSED
) {
1670 Error_Context
cntxt(index_value
, "In index value");
1671 index_value
->chk_expr_int(expected_index
);
1673 Value
*v_last
= index_value
->get_value_refd_last();
1674 if (v_last
->get_valuetype() == Value::V_INT
) {
1675 const int_val_t
*index_int
= v_last
->get_val_Int();
1676 if (*index_int
> INT_MAX
) {
1677 index_value
->error("Integer value `%s' is too big for indexing "
1678 "type `%s'", (index_int
->t_str()).c_str(),
1679 (t
->get_typename()).c_str());
1680 index_value
->set_valuetype(Value::V_ERROR
);
1682 if (*index_int
< 0) {
1683 index_value
->error("A non-negative integer value was "
1684 "expected for indexing type `%s' instead of `%s'",
1685 t
->get_typename().c_str(), (index_int
->t_str()).c_str());
1686 index_value
->set_valuetype(Value::V_ERROR
);
1691 // change t to the embedded type
1695 FATAL_ERROR("Type::get_field_type(): invalid reference type");
1701 bool Type::get_subrefs_as_array(const Ttcn::FieldOrArrayRefs
*subrefs
, dynamic_array
<size_t>& subrefs_array
, dynamic_array
<Type
*>& type_array
)
1703 if (!subrefs
) FATAL_ERROR("Type::get_subrefs_as_array()");
1705 size_t nof_refs
= subrefs
->get_nof_refs();
1706 for (size_t i
= 0; i
< nof_refs
; i
++) {
1707 t
= t
->get_type_refd_last();
1709 if (t
->typetype
== T_ERROR
) FATAL_ERROR("Type::get_subrefs_as_array()");
1710 Ttcn::FieldOrArrayRef
*ref
= subrefs
->get_ref(i
);
1711 size_t field_index
=0;
1712 switch (ref
->get_type()) {
1713 case Ttcn::FieldOrArrayRef::FIELD_REF
: {
1714 const Identifier
& id
= *ref
->get_id();
1715 if (!t
->has_comp_withName(id
)) FATAL_ERROR("Type::get_subrefs_as_array()");
1716 CompField
* cf
= t
->get_comp_byName(id
);
1717 field_index
= t
->get_comp_index_byName(id
);
1718 field_index
= t
->get_codegen_index(field_index
);
1721 case Ttcn::FieldOrArrayRef::ARRAY_REF
: {
1722 Value
*index_value
= ref
->get_val();
1723 Value
*v_last
= index_value
->get_value_refd_last();
1724 if (v_last
->get_valuetype()!=Value::V_INT
) {
1725 // workaround: get_field_type() does not return NULL if the index
1726 // value is invalid, this function returns false in this case
1729 const int_val_t
*index_int
= v_last
->get_val_Int();
1730 if (!index_int
->is_native() || index_int
->is_negative()) {
1733 field_index
= (size_t)index_int
->get_val();
1734 Type
*embedded_type
= 0;
1735 switch (t
->typetype
) {
1738 embedded_type
= t
->u
.seof
.ofType
;
1741 embedded_type
= t
->u
.array
.element_type
;
1747 // change t to the embedded type
1751 FATAL_ERROR("Type::get_subrefs_as_array()");
1753 subrefs_array
.add(field_index
);
1758 bool Type::is_optional_field() const {
1759 if (ownertype
== OT_COMP_FIELD
) {
1760 const CompField
* const myOwner
= (CompField
*) owner
;
1761 return myOwner
&& myOwner
->get_is_optional();
1766 bool Type::field_is_optional(Ttcn::FieldOrArrayRefs
*subrefs
)
1768 // handling trivial cases
1769 if (!subrefs
) return false;
1770 size_t nof_subrefs
= subrefs
->get_nof_refs();
1771 if (nof_subrefs
< 1) return false;
1772 Ttcn::FieldOrArrayRef
*last_ref
= subrefs
->get_ref(nof_subrefs
- 1);
1773 if (last_ref
->get_type() == Ttcn::FieldOrArrayRef::ARRAY_REF
) return false;
1774 // following the embedded types
1775 Type
*t
=get_type_refd_last();
1776 for (size_t i
= 0; i
< nof_subrefs
- 1; i
++) {
1777 Ttcn::FieldOrArrayRef
*ref
= subrefs
->get_ref(i
);
1778 if (ref
->get_type() == Ttcn::FieldOrArrayRef::FIELD_REF
)
1779 t
= t
->get_comp_byName(*ref
->get_id())->get_type();
1780 else t
= t
->get_ofType();
1781 t
=t
->get_type_refd_last();
1783 // now last_ref refers to a field of t
1784 return t
->get_comp_byName(*last_ref
->get_id())->get_is_optional();
1787 bool Type::is_root_basic(){
1788 Type
*t
=get_type_refd_last();
1789 switch(t
->typetype
){
1804 int Type::get_raw_length(){
1805 if(!raw_checked
) FATAL_ERROR("Type::get_raw_length()");
1806 if(raw_length_calculated
) return raw_length
;
1807 raw_length_calculated
=true;
1810 raw_length
=get_type_refd()->get_raw_length();
1813 if(rawattrib
) raw_length
=rawattrib
->fieldlength
;
1817 if(rawattrib
) raw_length
=rawattrib
->fieldlength
;
1824 if(rawattrib
&& rawattrib
->fieldlength
) raw_length
=rawattrib
->fieldlength
;
1828 if(rawattrib
&& rawattrib
->fieldlength
) raw_length
=rawattrib
->fieldlength
;
1831 int max_val
=u
.enums
.first_unused
;
1832 for(size_t a
=0;a
<u
.enums
.eis
->get_nof_eis();a
++){
1833 int val
=u
.enums
.eis
->get_ei_byIndex(a
)->get_value()->get_val_Int()
1835 if((max_val
<0?-max_val
:max_val
)<(val
<0?-val
:val
)) max_val
=val
;
1837 if(max_val
<0){ min_bits
=1;max_val
=-max_val
;}
1838 while(max_val
){ min_bits
++; max_val
/=2;}
1839 raw_length
=min_bits
;
1845 for(size_t i
= 0; i
< get_nof_comps(); i
++){
1847 CompField
* cf
=get_comp_byIndex(i
);
1848 if(cf
->get_is_optional()){
1852 l
=cf
->get_type()->get_raw_length();
1857 if(cf
->get_type()->rawattrib
1858 && (cf
->get_type()->rawattrib
->pointerto
1859 || cf
->get_type()->rawattrib
->lengthto_num
)){
1866 // TODO: case T_ANYTYPE: for get_raw_length needed ?
1868 for(size_t i
= 0; i
< get_nof_comps(); i
++){
1869 CompField
*cf
=get_comp_byIndex(i
);
1871 l
=cf
->get_type()->get_raw_length();
1892 /** \todo: add extra checks and warnings for unsupported attributes
1893 * e.g. when TAG refers to a record/set field which has union type */
1894 void Type::chk_raw()
1896 bool self_ref
= false;
1897 if (raw_checked
) return;
1899 if (!enable_raw()) return;
1902 restrlength
=(int)sub_type
->get_length_restriction();
1903 if(restrlength
!=-1){
1905 Type
*t
=get_type_refd_last();
1906 typetype_t basic_type
=t
->typetype
;
1907 rawattrib
=new RawAST(basic_type
==T_INT
);
1908 if(basic_type
==T_REAL
) rawattrib
->fieldlength
=64;
1910 rawattrib
->length_restrition
=restrlength
;
1912 if(!rawattrib
) return;
1915 get_type_refd()->force_raw();
1916 if(rawattrib
->fieldlength
==0 && rawattrib
->length_restrition
!=-1){
1917 typetype_t basic_type
=get_type_refd_last()->typetype
;
1920 rawattrib
->fieldlength
=rawattrib
->length_restrition
;
1921 rawattrib
->length_restrition
=-1;
1924 rawattrib
->fieldlength
=rawattrib
->length_restrition
*4;
1925 rawattrib
->length_restrition
=-1;
1928 rawattrib
->fieldlength
=rawattrib
->length_restrition
*8;
1929 rawattrib
->length_restrition
=-1;
1932 rawattrib
->fieldlength
=rawattrib
->length_restrition
*8;
1933 rawattrib
->length_restrition
=-1;
1937 rawattrib
->fieldlength
=rawattrib
->length_restrition
;
1938 rawattrib
->length_restrition
=-1;
1947 size_t nof_comps
= get_nof_comps();
1948 for (size_t i
= 0; i
< nof_comps
; i
++)
1949 get_comp_byIndex(i
)->get_type()->force_raw();
1950 for(int c
=0;c
<rawattrib
->taglist
.nElements
;c
++){
1951 Identifier
*idf
=rawattrib
->taglist
.tag
[c
].fieldName
;
1952 if(!has_comp_withName(*idf
)){
1953 error("Invalid field name `%s' in RAW parameter TAG for type `%s'",
1954 idf
->get_dispname().c_str(), get_typename().c_str());
1957 size_t fieldnum
= get_comp_index_byName(*idf
);
1958 for(int a
=0;a
<rawattrib
->taglist
.tag
[c
].nElements
;a
++){
1960 CompField
*cf
=get_comp_byIndex(fieldnum
);
1961 Type
*t
=cf
->get_type()->get_type_refd_last();
1962 for(int b
=0;b
<rawattrib
->taglist
.tag
[c
].keyList
[a
].
1963 keyField
->nElements
;b
++){
1965 rawattrib
->taglist
.tag
[c
].keyList
[a
].keyField
->names
[b
];
1967 error("Invalid fieldmember type in RAW parameter TAG"
1969 ,cf
->get_name().get_dispname().c_str());
1973 if(!t
->has_comp_withName(*idf2
)){
1974 error("Invalid field member name `%s' in RAW parameter TAG "
1975 "for field `%s'", idf2
->get_dispname().c_str(),
1976 cf
->get_name().get_dispname().c_str());
1980 size_t comp_index
=t
->get_comp_index_byName(*idf2
);
1981 CompField
*cf2
=t
->get_comp_byIndex(comp_index
);
1982 t
=cf2
->get_type()->get_type_refd_last();
1985 Error_Context
cntx(this, "In Raw parmeter TAG");
1986 Value
*v
= rawattrib
->taglist
.tag
[c
].keyList
[a
].v_value
;
1987 v
->set_my_scope(get_my_scope());
1988 v
->set_my_governor(t
);
1989 t
->chk_this_value_ref(v
);
1990 self_ref
= t
->chk_this_value(v
, 0, EXPECTED_CONSTANT
,
1991 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
1992 Value::valuetype_t vt
= v
->get_valuetype();
1993 if (vt
== Value::V_ENUM
|| vt
== Value::V_REFD
) {
1994 Free(rawattrib
->taglist
.tag
[c
].keyList
[a
].value
);
1995 rawattrib
->taglist
.tag
[c
].keyList
[a
].value
=
1996 mcopystr(v
->get_single_expr().c_str());
2007 for(int c
=0;c
<rawattrib
->taglist
.nElements
;c
++) { // check TAG
2008 Identifier
*idf
=rawattrib
->taglist
.tag
[c
].fieldName
;
2009 if(!has_comp_withName(*idf
)){
2010 error("Invalid field name `%s' in RAW parameter TAG "
2011 "for type `%s'", idf
->get_dispname().c_str(),
2012 get_typename().c_str());
2015 fieldnum
=get_comp_index_byName(*idf
);
2016 for(int a
=0;a
<rawattrib
->taglist
.tag
[c
].nElements
;a
++){
2018 CompField
*cf
=get_comp_byIndex(fieldnum
);
2019 Type
*t
=cf
->get_type()->get_type_refd_last();
2020 for(int b
=0;b
<rawattrib
->taglist
.tag
[c
].keyList
[a
].
2021 keyField
->nElements
;b
++){
2023 rawattrib
->taglist
.tag
[c
].keyList
[a
].keyField
->names
[b
];
2025 error("Invalid fieldmember type in RAW parameter TAG"
2027 ,cf
->get_name().get_dispname().c_str());
2031 if(!t
->has_comp_withName(*idf2
)){
2032 error("Invalid field member name `%s' in RAW parameter TAG "
2033 "for field `%s'", idf2
->get_dispname().c_str(),
2034 cf
->get_name().get_dispname().c_str());
2038 size_t comp_index
=t
->get_comp_index_byName(*idf2
);
2039 CompField
*cf2
=t
->get_comp_byIndex(comp_index
);
2040 t
=cf2
->get_type()->get_type_refd_last();
2043 Error_Context
cntx(this, "In Raw parmeter TAG");
2044 Value
*v
= rawattrib
->taglist
.tag
[c
].keyList
[a
].v_value
;
2045 v
->set_my_scope(get_my_scope());
2046 v
->set_my_governor(t
);
2047 t
->chk_this_value_ref(v
);
2048 self_ref
= t
->chk_this_value(v
, 0, EXPECTED_CONSTANT
,
2049 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
2050 Value::valuetype_t vt
= v
->get_valuetype();
2051 if (vt
== Value::V_ENUM
|| vt
== Value::V_REFD
) {
2052 Free(rawattrib
->taglist
.tag
[c
].keyList
[a
].value
);
2053 rawattrib
->taglist
.tag
[c
].keyList
[a
].value
=
2054 mcopystr(v
->get_single_expr().c_str());
2059 for(int a
=0; a
<rawattrib
->ext_bit_goup_num
;a
++){ // EXTENSION_BIT_GROUP
2060 Identifier
*idf
=rawattrib
->ext_bit_groups
[a
].from
;
2061 Identifier
*idf2
=rawattrib
->ext_bit_groups
[a
].to
;
2063 if(!has_comp_withName(*idf
)){
2064 error("Invalid field name `%s' in RAW parameter "
2065 "EXTENSION_BIT_GROUP for type `%s'",
2066 idf
->get_dispname().c_str(), get_typename().c_str());
2069 if(!has_comp_withName(*idf2
)){
2070 error("Invalid field name `%s' in RAW parameter "
2071 "EXTENSION_BIT_GROUP for type `%s'",
2072 idf2
->get_dispname().c_str(), get_typename().c_str());
2076 size_t kezd
=get_comp_index_byName(*idf
);
2077 size_t veg
=get_comp_index_byName(*idf2
);
2079 error("Invalid field order in RAW parameter "
2080 "EXTENSION_BIT_GROUP for type `%s': `%s', `%s'",
2081 get_typename().c_str(), idf
->get_dispname().c_str(),
2082 idf2
->get_dispname().c_str());
2087 if(rawattrib
->paddall
!=XDEFDEFAULT
){ // PADDALL
2088 for(size_t i
= 0; i
< get_nof_comps(); i
++) {
2089 CompField
*cfield
=get_comp_byIndex(i
);
2090 RawAST
*field_rawattr
=cfield
->get_type()->rawattrib
;
2091 if(field_rawattr
==NULL
){
2092 Type
*t
=cfield
->get_type()->get_type_refd_last();
2093 typetype_t basic_type
=t
->typetype
;
2094 t
=cfield
->get_type();
2095 if(t
->is_ref()) t
=t
->get_type_refd();
2096 while(!t
->rawattrib
&& t
->is_ref()) t
=t
->get_type_refd();
2097 field_rawattr
= new RawAST(t
->rawattrib
,basic_type
==T_INT
);
2098 if(!t
->rawattrib
&& basic_type
==T_REAL
) field_rawattr
->fieldlength
=64;
2099 cfield
->get_type()->rawattrib
=field_rawattr
;
2101 if(field_rawattr
->padding
==0)
2102 field_rawattr
->padding
=rawattrib
->padding
;
2103 if(field_rawattr
->prepadding
==0)
2104 field_rawattr
->prepadding
=rawattrib
->prepadding
;
2105 if (field_rawattr
->padding_pattern_length
== 0 &&
2106 rawattrib
->padding_pattern_length
> 0) {
2107 Free(field_rawattr
->padding_pattern
);
2108 field_rawattr
->padding_pattern
=
2109 mcopystr(rawattrib
->padding_pattern
);
2110 field_rawattr
->padding_pattern_length
=
2111 rawattrib
->padding_pattern_length
;
2115 if(rawattrib
->fieldorder
!=XDEFDEFAULT
){ // FIELDORDER
2116 for(size_t i
= 0; i
< get_nof_comps(); i
++) {
2117 CompField
*cfield
=get_comp_byIndex(i
);
2118 RawAST
*field_rawattr
=cfield
->get_type()->rawattrib
;
2119 if(field_rawattr
==NULL
){
2120 Type
*t
=cfield
->get_type()->get_type_refd_last();
2121 typetype_t basic_type
=t
->typetype
;
2122 t
=cfield
->get_type();
2123 if(t
->is_ref()) t
=t
->get_type_refd();
2124 while(!t
->rawattrib
&& t
->is_ref()) t
=t
->get_type_refd();
2125 field_rawattr
= new RawAST(t
->rawattrib
,basic_type
==T_INT
);
2126 if(!t
->rawattrib
&& basic_type
==T_REAL
) field_rawattr
->fieldlength
=64;
2127 cfield
->get_type()->rawattrib
=field_rawattr
;
2129 if(field_rawattr
->fieldorder
==XDEFDEFAULT
)
2130 field_rawattr
->fieldorder
=rawattrib
->fieldorder
;
2134 for(int a
=0;a
<rawattrib
->presence
.nElements
;a
++){ //PRESENCE
2137 for(int b
=0;b
<rawattrib
->presence
.keyList
[a
].keyField
->nElements
;b
++){
2138 Identifier
*idf
=rawattrib
->presence
.keyList
[a
].keyField
->names
[b
];
2140 error("Invalid fieldmember type in RAW parameter PRESENCE"
2141 " for the record %s."
2142 ,get_typename().c_str());
2146 if(!t
->has_comp_withName(*idf
)){
2147 error("Invalid fieldname in RAW parameter"
2148 " PRESENCE for the record %s: %s"
2149 ,get_typename().c_str()
2150 ,rawattrib
->presence
.keyList
[a
].keyField
->names
[b
]
2151 ->get_dispname().c_str());
2155 t
=t
->get_comp_byName(*idf
)->get_type()->get_type_refd_last();
2158 Error_Context
cntx(this, "In Raw parameter PRESENCE");
2159 Value
*v
= rawattrib
->presence
.keyList
[a
].v_value
;
2160 v
->set_my_scope(get_my_scope());
2161 v
->set_my_governor(t
);
2162 t
->chk_this_value_ref(v
);
2163 self_ref
= t
->chk_this_value(v
, 0, EXPECTED_CONSTANT
,
2164 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
2165 Value::valuetype_t vt
= v
->get_valuetype();
2166 if (vt
== Value::V_ENUM
|| vt
== Value::V_REFD
) {
2167 Free(rawattrib
->presence
.keyList
[a
].value
);
2168 rawattrib
->presence
.keyList
[a
].value
=
2169 mcopystr(v
->get_single_expr().c_str());
2173 for(size_t i
= 0; i
< get_nof_comps(); i
++) { // field attributes
2174 CompField
*cf
= get_comp_byIndex(i
);
2175 const Identifier
& field_id
= cf
->get_name();
2176 Type
*field_type
= cf
->get_type();
2177 Type
*field_type_last
= field_type
->get_type_refd_last();
2178 field_type
->force_raw();
2179 RawAST
*rawpar
= field_type
->rawattrib
;
2181 for (int j
= 0; j
< rawpar
->lengthto_num
; j
++) { // LENGTHTO
2182 Identifier
*idf
= rawpar
->lengthto
[j
];
2183 if (!has_comp_withName(*idf
)) {
2184 error("Invalid fieldname in RAW parameter "
2185 "LENGTHTO for field %s: %s",
2186 field_id
.get_dispname().c_str(),
2187 rawpar
->lengthto
[j
]->get_dispname().c_str());
2190 if (rawpar
->lengthto_num
) {
2191 Type
*ft
= field_type
;
2192 if (ft
->get_typetype() == T_REFD
) ft
= ft
->get_type_refd_last();
2193 typetype_t ftt
= ft
->get_typetype();
2200 for (size_t fi
= 0; fi
< ft
->get_nof_comps(); fi
++) {
2201 typetype_t uftt
= ft
->get_comp_byIndex(fi
)->get_type()
2203 if (uftt
!= T_INT
&& uftt
!= T_INT_A
)
2204 error("The union type LENGTHTO field must contain only "
2214 if (rawpar
->lengthindex
) break; // Will be checked in the next step.
2215 // Else continue with default.
2217 error("The LENGTHTO field must be an integer or union type "
2218 "instead of `%s'", ft
->get_typename().c_str());
2222 if(rawpar
->lengthto_num
&& rawpar
->lengthindex
){ // LENGTHINDEX
2223 Identifier
*idf
=rawpar
->lengthindex
->names
[0];
2224 if(!field_type_last
->is_secho()){
2225 error("Invalid fieldmember type in RAW parameter LENGTHINDEX"
2227 ,field_id
.get_dispname().c_str());
2230 if(!field_type_last
->has_comp_withName(*idf
))
2231 error("Invalid fieldname in RAW parameter"
2232 " LENGTHINDEX for field %s: %s"
2233 ,field_id
.get_dispname().c_str()
2234 ,rawpar
->lengthindex
->names
[0]->get_dispname().c_str());
2236 if(rawpar
->pointerto
){ // POINTERTO
2237 Identifier
*idf
=rawpar
->pointerto
;
2240 if(!has_comp_withName(*idf
)){
2241 error("Invalid fieldname in RAW"
2242 " parameter POINTERTO for field %s: %s"
2243 ,field_id
.get_dispname().c_str()
2244 ,rawpar
->pointerto
->get_dispname().c_str());
2247 if(!hiba
&& (pointed
=get_comp_index_byName(*idf
))<=i
){
2248 error("Pointer must precede the pointed field. Incorrect field "
2249 "name `%s' in RAW parameter POINTERTO for field `%s'",
2250 rawpar
->pointerto
->get_dispname().c_str(),
2251 field_id
.get_dispname().c_str());
2254 if(!hiba
&& rawpar
->ptrbase
){ // POINTERTO
2255 Identifier
*idf2
=rawpar
->ptrbase
;
2256 if(!has_comp_withName(*idf2
)){
2257 error("Invalid field name `%s' in RAW parameter PTROFFSET for "
2258 "field `%s'", rawpar
->ptrbase
->get_dispname().c_str(),
2259 field_id
.get_dispname().c_str());
2262 if(!hiba
&& get_comp_index_byName(*idf2
)>pointed
){
2263 error("Pointer base must precede the pointed field. Incorrect "
2264 "field name `%s' in RAW parameter PTROFFSET for field "
2265 "`%s'", rawpar
->ptrbase
->get_dispname().c_str(),
2266 field_id
.get_dispname().c_str());
2270 for(int a
=0;a
<rawpar
->presence
.nElements
;a
++){ //PRESENCE
2273 for(int b
=0;b
<rawpar
->presence
.keyList
[a
].keyField
->nElements
;b
++){
2274 Identifier
*idf
=rawpar
->presence
.keyList
[a
].keyField
->names
[b
];
2276 error("Invalid fieldmember type in RAW parameter PRESENCE"
2278 ,field_id
.get_dispname().c_str());
2282 if(!t
->has_comp_withName(*idf
)){
2283 error("Invalid fieldname `%s' in RAW parameter PRESENCE for "
2284 "field `%s'", rawpar
->presence
.keyList
[a
].keyField
2285 ->names
[b
]->get_dispname().c_str(),
2286 field_id
.get_dispname().c_str());
2290 if(b
==0 && !(get_comp_index_byName(*rawpar
->presence
.keyList
[a
]
2291 .keyField
->names
[0])<i
)){
2292 error("The PRESENCE field `%s' must precede the optional field "
2293 "in RAW parameter PRESENCE for field `%s'"
2294 ,rawpar
->presence
.keyList
[a
].keyField
->names
[0]
2295 ->get_dispname().c_str()
2296 ,field_id
.get_dispname().c_str());
2300 t
=t
->get_comp_byName(*idf
)->get_type()->get_type_refd_last();
2303 Error_Context
cntx(this, "In Raw parmeter PRESENCE");
2304 Value
*v
= rawpar
->presence
.keyList
[a
].v_value
;
2305 v
->set_my_scope(get_my_scope());
2306 v
->set_my_governor(t
);
2307 t
->chk_this_value_ref(v
);
2308 self_ref
= t
->chk_this_value(v
, 0, EXPECTED_CONSTANT
,
2309 INCOMPLETE_NOT_ALLOWED
, OMIT_NOT_ALLOWED
, SUB_CHK
);
2310 Value::valuetype_t vt
= v
->get_valuetype();
2311 if (vt
== Value::V_ENUM
|| vt
== Value::V_REFD
) {
2312 Free(rawpar
->presence
.keyList
[a
].value
);
2313 rawpar
->presence
.keyList
[a
].value
=
2314 mcopystr(v
->get_single_expr().c_str());
2318 for(int c
=0;c
<rawpar
->crosstaglist
.nElements
;c
++) { // CROSSTAG
2319 Identifier
*idf
=rawpar
->crosstaglist
.tag
[c
].fieldName
;
2320 if(!field_type_last
->is_secho()){
2321 error("Invalid fieldmember type in RAW parameter CROSSTAG"
2323 ,field_id
.get_dispname().c_str());
2326 if(!field_type_last
->has_comp_withName(*idf
)){
2327 error("Invalid fieldmember name in RAW parameter CROSSTAG"
2329 ,field_id
.get_dispname().c_str()
2330 ,rawpar
->crosstaglist
.tag
[c
].fieldName
2331 ->get_dispname().c_str());
2334 for(int a
=0;a
<rawpar
->crosstaglist
.tag
[c
].nElements
;a
++){
2337 bool allow_omit
= false;
2339 b
<rawpar
->crosstaglist
.tag
[c
].keyList
[a
].keyField
->nElements
;b
++){
2341 rawpar
->crosstaglist
.tag
[c
].keyList
[a
].keyField
->names
[b
];
2342 if(!t2
->is_secho()){
2343 error("Invalid fieldmember type in RAW parameter CROSSTAG"
2345 ,field_id
.get_dispname().c_str());
2349 if(!t2
->has_comp_withName(*idf2
)){
2350 error("Invalid fieldname in RAW parameter CROSSTAG"
2352 ,field_id
.get_dispname().c_str()
2353 ,idf2
->get_dispname().c_str());
2358 size_t field_idx
= get_comp_index_byName(*idf2
);
2359 if (field_idx
== i
) {
2360 error("RAW parameter CROSSTAG for field `%s' cannot refer "
2361 "to the field itself", idf2
->get_dispname().c_str());
2362 } else if (field_idx
> i
) {
2363 if (cf
->get_is_optional() ||
2364 field_type
->get_raw_length() < 0)
2365 error("Field `%s' that CROSSTAG refers to must precede "
2366 "field `%s' or field `%s' must be mandatory with "
2367 "fixed length", idf2
->get_dispname().c_str(),
2368 field_id
.get_dispname().c_str(),
2369 field_id
.get_dispname().c_str());
2372 CompField
*cf2
=t2
->get_comp_byName(*idf2
);
2373 t2
=cf2
->get_type()->get_type_refd_last();
2374 if (b
== rawpar
->crosstaglist
.tag
[c
].keyList
[a
].keyField
2375 ->nElements
- 1 && cf2
->get_is_optional())
2379 Error_Context
cntx(this, "In Raw parmeter CROSSTAG");
2380 Value
*v
= rawpar
->crosstaglist
.tag
[c
].keyList
[a
].v_value
;
2381 v
->set_my_scope(get_my_scope());
2382 v
->set_my_governor(t2
);
2383 t2
->chk_this_value_ref(v
);
2384 self_ref
= t2
->chk_this_value(v
, 0, EXPECTED_CONSTANT
,
2385 INCOMPLETE_NOT_ALLOWED
,
2386 (allow_omit
? OMIT_ALLOWED
: OMIT_NOT_ALLOWED
), SUB_CHK
);
2387 Value::valuetype_t vt
= v
->get_valuetype();
2388 if (vt
== Value::V_ENUM
|| vt
== Value::V_REFD
) {
2389 Free(rawpar
->crosstaglist
.tag
[c
].keyList
[a
].value
);
2390 rawpar
->crosstaglist
.tag
[c
].keyList
[a
].value
=
2391 mcopystr(v
->get_single_expr().c_str());
2400 if(rawattrib
->fieldlength
==0 && rawattrib
->length_restrition
!=-1){
2401 rawattrib
->fieldlength
=rawattrib
->length_restrition
;
2402 rawattrib
->length_restrition
=-1;
2406 if(rawattrib
->fieldlength
==0 && rawattrib
->length_restrition
!=-1){
2407 rawattrib
->fieldlength
=rawattrib
->length_restrition
*4;
2408 rawattrib
->length_restrition
=-1;
2412 if(rawattrib
->fieldlength
==0 && rawattrib
->length_restrition
!=-1){
2413 rawattrib
->fieldlength
=rawattrib
->length_restrition
*8;
2414 rawattrib
->length_restrition
=-1;
2418 if(rawattrib
->fieldlength
==0 && rawattrib
->length_restrition
!=-1){
2419 rawattrib
->fieldlength
=rawattrib
->length_restrition
*8;
2420 rawattrib
->length_restrition
=-1;
2425 get_ofType()->force_raw();
2426 if(rawattrib
->fieldlength
==0 && rawattrib
->length_restrition
!=-1){
2427 rawattrib
->fieldlength
=rawattrib
->length_restrition
;
2428 rawattrib
->length_restrition
=-1;
2430 if(rawattrib
->length_restrition
!=-1 &&
2431 rawattrib
->length_restrition
!=rawattrib
->fieldlength
){
2432 error("Invalid length specified in parameter FIELDLENGTH for %s of "
2433 "type `%s'. The FIELDLENGTH must be equal to specified length "
2434 "restriction", typetype
== T_SEQOF
? "record" : "set",
2435 get_fullname().c_str());
2439 if(rawattrib
->fieldlength
!=64 && rawattrib
->fieldlength
!=32){
2440 error("Invalid length (%d) specified in parameter FIELDLENGTH for "
2441 "float type `%s'. The FIELDLENGTH must be single (32) or double "
2442 "(64)", rawattrib
->fieldlength
, get_fullname().c_str());
2449 // nothing to do, ASN1 types or types without defined raw attribute
2456 void Type::force_raw()
2464 // TODO case T_ANYTYPE: for force_raw ?
2468 rawattrib
= new RawAST(false);
2471 if (is_ref()) get_type_refd()->force_raw();
2476 // Don't run chk_raw() on unchecked types
2481 void Type::chk_text()
2483 if (text_checked
) return;
2484 text_checked
= true;
2485 if (!textattrib
|| !enable_text()) return;
2486 //textattrib->print_TextAST();
2488 chk_text_matching_values(textattrib
->begin_val
, "BEGIN");
2489 chk_text_matching_values(textattrib
->end_val
, "END");
2490 chk_text_matching_values(textattrib
->separator_val
, "SEPARATOR");
2497 size_t nof_comps
= get_nof_comps();
2498 for (size_t i
= 0; i
< nof_comps
; i
++)
2499 get_comp_byIndex(i
)->get_type()->force_text();
2503 get_ofType()->force_text();
2506 if (is_ref()) get_type_refd()->force_text();
2510 switch (get_type_refd_last()->typetype
) {
2512 chk_text_matching_values(textattrib
->true_params
, "true value");
2513 chk_text_matching_values(textattrib
->false_params
, "false value");
2516 if(textattrib
->nof_field_params
){
2517 Type
*t
=get_type_refd_last();
2518 size_t nof_comps
= t
->u
.enums
.eis
->get_nof_eis();
2519 textAST_enum_def
**params
=(textAST_enum_def
**)
2520 Malloc(nof_comps
*sizeof(textAST_enum_def
*));
2521 memset(params
,0,nof_comps
*sizeof(textAST_enum_def
*));
2522 for (int a
= 0; a
< textattrib
->nof_field_params
; a
++) {
2523 const Identifier
& id
= *textattrib
->field_params
[a
]->name
;
2524 if (t
->u
.enums
.eis
->has_ei_withName(id
)) {
2525 int index
= t
->get_eis_index_byName(id
);
2526 if (params
[index
]) FATAL_ERROR("Type::chk_text(): duplicate " \
2527 "attribute for enum `%s'", id
.get_dispname().c_str());
2528 params
[index
] = textattrib
->field_params
[a
];
2529 char *attrib_name
= mprintf("enumerated value `%s'",
2530 id
.get_dispname().c_str());
2531 chk_text_matching_values(¶ms
[index
]->value
, attrib_name
);
2534 error("Coding attribute refers to non-existent enumerated value "
2535 "`%s'", id
.get_dispname().c_str());
2536 Free(textattrib
->field_params
[a
]->value
.encode_token
);
2537 Free(textattrib
->field_params
[a
]->value
.decode_token
);
2538 delete textattrib
->field_params
[a
]->name
;
2539 Free(textattrib
->field_params
[a
]);
2542 Free(textattrib
->field_params
);
2543 textattrib
->field_params
=params
;
2544 textattrib
->nof_field_params
=nof_comps
;
2550 if (textattrib
->decode_token
) {
2551 char *tmp
= textattrib
->decode_token
;
2552 textattrib
->decode_token
= process_decode_token(tmp
, *this);
2554 tmp
= TTCN_pattern_to_regexp(textattrib
->decode_token
);
2557 error("Incorrect select token expression: `%s'",
2558 textattrib
->decode_token
);
2565 //textattrib->print_TextAST();
2568 void Type::chk_text_matching_values(textAST_matching_values
*matching_values
,
2569 const char *attrib_name
)
2571 if (!matching_values
) return;
2572 if (matching_values
->decode_token
) {
2573 // check whether decode token is a correct TTCN-3 pattern
2574 char *tmp
= matching_values
->decode_token
;
2575 matching_values
->decode_token
= process_decode_token(tmp
, *this);
2577 tmp
= TTCN_pattern_to_regexp(matching_values
->decode_token
);
2580 error("Incorrect matching expression for %s: `%s'", attrib_name
,
2581 matching_values
->decode_token
);
2583 } else if (matching_values
->encode_token
) {
2584 // the decode token is not present, but there is an encode token
2585 // derive the decode token from the encode token
2586 matching_values
->generated_decode_token
= true;
2587 matching_values
->decode_token
=
2588 convert_charstring_to_pattern(matching_values
->encode_token
);
2592 void Type::force_text()
2600 // TODO case T_ANYTYPE: for force_text ?
2604 textattrib
= new TextAST
;
2607 if (is_ref()) get_type_refd()->force_text();
2615 void Type::chk_json()
2617 if (json_checked
) return;
2618 json_checked
= true;
2619 if ((NULL
== jsonattrib
&& !hasEncodeAttr(CT_JSON
)) || !enable_json()) return;
2629 size_t nof_comps
= get_nof_comps();
2630 for (size_t i
= 0; i
< nof_comps
; i
++)
2631 get_comp_byIndex(i
)->get_type()->force_json();
2635 get_ofType()->force_json();
2638 if (is_ref()) get_type_refd()->force_json();
2642 if (NULL
!= jsonattrib
) {
2643 if (jsonattrib
->omit_as_null
&& !is_optional_field()) {
2644 error("Invalid attribute, 'omit as null' requires optional "
2645 "field of a record or set.");
2648 if (jsonattrib
->as_value
&& T_CHOICE_T
!= get_type_refd_last()->typetype
) {
2649 error("Invalid attribute, 'as value' is only allowed for unions");
2652 if (NULL
!= jsonattrib
->alias
) {
2653 Type
* parent
= get_parent_type();
2654 if (NULL
== parent
|| (T_SEQ_T
!= parent
->typetype
&&
2655 T_SET_T
!= parent
->typetype
&& T_CHOICE_T
!= parent
->typetype
)) {
2656 error("Invalid attribute, 'name as ...' requires field of a "
2657 "record, set or union.");
2659 if (NULL
!= parent
&& NULL
!= parent
->jsonattrib
&&
2660 T_CHOICE_T
== parent
->typetype
&& parent
->jsonattrib
->as_value
) {
2661 warning("Attribute 'name as ...' will be ignored, because parent union "
2662 "is encoded without field names.");
2666 if (NULL
!= jsonattrib
->default_value
) {
2672 void Type::chk_json_default()
2674 const char* dval
= jsonattrib
->default_value
;
2675 const size_t dval_len
= strlen(dval
);
2676 Type
*last
= get_type_refd_last();
2678 switch (last
->typetype
) {
2680 if (strcmp(dval
, "true") != 0 && strcmp(dval
, "false") != 0) {
2685 for (size_t i
= (dval
[0] == '-') ? 1 : 0; i
< dval_len
; ++i
) {
2686 if (dval
[i
] < '0' || dval
[i
] > '9') {
2688 break; // from the loop
2693 if (strcmp(dval
, "infinity") == 0 || strcmp(dval
, "-infinity") == 0 ||
2694 strcmp(dval
, "not_a_number") == 0) {
2695 // special float values => skip the rest of the check
2699 boolean first_digit
= false; // first non-zero digit reached
2700 boolean zero
= false; // first zero digit reached
2701 boolean decimal_point
= false; // decimal point (.) reached
2702 boolean exponent_mark
= false; // exponential mark (e or E) reached
2703 boolean exponent_sign
= false; // sign of the exponential (- or +) reached
2705 size_t i
= (dval
[0] == '-') ? 1 : 0;
2706 while(!err
&& i
< dval_len
) {
2709 if (decimal_point
|| exponent_mark
|| (!first_digit
&& !zero
)) {
2712 decimal_point
= true;
2713 first_digit
= false;
2718 if (exponent_mark
|| (!first_digit
&& !zero
)) {
2721 exponent_mark
= true;
2722 first_digit
= false;
2726 if (!first_digit
&& (exponent_mark
|| (!decimal_point
&& zero
))) {
2740 if (!first_digit
&& zero
&& (!decimal_point
|| exponent_mark
)) {
2747 if (exponent_sign
|| !exponent_mark
|| zero
|| first_digit
) {
2750 exponent_sign
= true;
2757 err
= !first_digit
&& !zero
;
2760 for (size_t i
= 0; i
< dval_len
; ++i
) {
2761 if (dval
[i
] < '0' || dval
[i
] > '1') {
2763 break; // from the loop
2768 if (dval_len
% 2 != 0) {
2774 for (size_t i
= 0; i
< dval_len
; ++i
) {
2775 if ((dval
[i
] < '0' || dval
[i
] > '9') && (dval
[i
] < 'a' || dval
[i
] > 'f') &&
2776 (dval
[i
] < 'A' || dval
[i
] > 'F')) {
2778 break; // from the loop
2785 while(!err
&& i
< dval_len
) {
2786 if (dval
[i
] < 0 && last
->typetype
== T_CSTR
) {
2789 else if (dval
[i
] == '\\') {
2790 if (i
== dval_len
- 1) {
2803 break; // these are OK
2805 if (i
+ 4 >= dval_len
) {
2807 } else if (last
->typetype
== T_CSTR
&&
2808 (dval
[i
+ 1] != '0' || dval
[i
+ 2] != '0' ||
2809 dval
[i
+ 3] < '0' || dval
[i
+ 3] > '7')) {
2812 for (size_t j
= (last
->typetype
== T_CSTR
) ? 4 : 1; j
<= 4; ++j
) {
2813 if ((dval
[i
+ j
] < '0' || dval
[i
+ j
] > '9') &&
2814 (dval
[i
+ j
] < 'a' || dval
[i
+ j
] > 'f') &&
2815 (dval
[i
+ j
] < 'A' || dval
[i
+ j
] > 'F')) {
2817 break; // from the loop
2833 Common::Identifier
id(Identifier::ID_TTCN
, string(dval
));
2834 if (!last
->has_ei_withName(id
)) {
2839 if (strcmp(dval
, "none") != 0 && strcmp(dval
, "pass") != 0 &&
2840 strcmp(dval
, "inconc") != 0 && strcmp(dval
, "fail") != 0 &&
2841 strcmp(dval
, "error") != 0) {
2846 error("JSON default values are not available for type `%s'",
2847 last
->get_stringRepr().c_str());
2852 if (last
->typetype
== T_ENUM_T
) {
2853 error("Invalid JSON default value for enumerated type `%s'",
2854 last
->get_stringRepr().c_str());
2856 error("Invalid %s JSON default value", get_typename_builtin(last
->typetype
));
2861 void Type::force_json()
2876 jsonattrib
= new JsonAST
;
2879 if (is_ref()) get_type_refd()->force_json();
2888 int Type::get_length_multiplier()
2892 return get_type_refd()->get_length_multiplier();
2907 /** \todo review, especially the string types... */
2908 bool Type::is_compatible_tt_tt(typetype_t p_tt1
, typetype_t p_tt2
,
2909 bool p_is_asn11
, bool p_is_asn12
)
2911 if (p_tt2
== T_ERROR
) return true;
2913 // error type is compatible with everything
2916 // unambiguous built-in types
2932 return p_tt1
== p_tt2
;
2934 return p_tt2
==T_OSTR
|| (!p_is_asn11
&& p_tt2
==T_ANY
);
2940 case T_UNIVERSALSTRING
:
2941 case T_TELETEXSTRING
:
2942 case T_VIDEOTEXSTRING
:
2943 case T_GRAPHICSTRING
:
2944 case T_OBJECTDESCRIPTOR
:
2945 case T_GENERALSTRING
:
2947 case T_NUMERICSTRING
:
2948 case T_PRINTABLESTRING
:
2950 case T_VISIBLESTRING
:
2952 case T_GENERALIZEDTIME
:
2957 // character string group 1
2960 case T_UNIVERSALSTRING
:
2965 case T_UNIVERSALSTRING
:
2967 case T_NUMERICSTRING
:
2968 case T_PRINTABLESTRING
:
2970 case T_VISIBLESTRING
:
2972 case T_GENERALIZEDTIME
:
2977 // character string group 2
2978 case T_TELETEXSTRING
:
2979 case T_VIDEOTEXSTRING
:
2980 case T_GRAPHICSTRING
:
2981 case T_OBJECTDESCRIPTOR
:
2982 case T_GENERALSTRING
:
2984 case T_TELETEXSTRING
:
2985 case T_VIDEOTEXSTRING
:
2986 case T_GRAPHICSTRING
:
2987 case T_OBJECTDESCRIPTOR
:
2988 case T_GENERALSTRING
:
2990 case T_NUMERICSTRING
:
2991 case T_PRINTABLESTRING
:
2993 case T_VISIBLESTRING
:
2995 case T_GENERALIZEDTIME
:
2998 // maybe :) is ustr.is_cstr()
3003 // character string group 3
3005 case T_NUMERICSTRING
:
3006 case T_PRINTABLESTRING
:
3008 case T_VISIBLESTRING
:
3010 case T_GENERALIZEDTIME
:
3013 case T_NUMERICSTRING
:
3014 case T_PRINTABLESTRING
:
3016 case T_VISIBLESTRING
:
3018 case T_GENERALIZEDTIME
:
3023 // polymorphic built-in types
3026 return p_tt2
== T_BSTR
|| p_tt2
== T_BSTR_A
;
3029 return p_tt2
== T_INT
|| p_tt2
== T_INT_A
;
3030 // ROID is visible as OID from TTCN-3
3032 return p_tt2
== T_OID
||
3033 (!p_is_asn11
&& p_tt2
== T_ROID
);
3035 return p_tt2
== T_ROID
||
3036 (!p_is_asn12
&& p_tt2
== T_OID
);
3039 return p_tt2
==T_ENUM_A
|| p_tt2
==T_ENUM_T
;
3043 return p_tt2
==T_CHOICE_T
|| p_tt2
==T_CHOICE_A
|| p_tt2
==T_OPENTYPE
;
3046 return p_tt2
==T_SEQ_A
|| p_tt2
==T_SEQ_T
;
3049 return p_tt2
==T_SET_A
|| p_tt2
==T_SET_T
;
3051 return p_tt2
== T_ANY
|| p_tt2
== T_OSTR
;
3052 // these should never appear?
3059 FATAL_ERROR("Type::is_compatible_tt_tt()");
3064 bool Type::is_compatible_tt(typetype_t p_tt
, bool p_is_asn1
)
3067 Type
*t1
=get_type_refd_last();
3068 if (p_tt
== T_ERROR
) return true;
3069 switch (t1
->typetype
) {
3070 // these should never appear
3075 FATAL_ERROR("Type::is_compatible_tt()");
3078 return is_compatible_tt_tt(t1
->typetype
, p_tt
, is_asn1(), p_is_asn1
);
3082 bool Type::is_compatible(Type
*p_type
, TypeCompatInfo
*p_info
,
3083 TypeChain
*p_left_chain
, TypeChain
*p_right_chain
)
3087 Type
*t1
= get_type_refd_last();
3088 Type
*t2
= p_type
->get_type_refd_last();
3089 // Error type is compatible with everything.
3090 if (t1
->typetype
== T_ERROR
|| t2
->typetype
== T_ERROR
) return true;
3092 switch (t1
->typetype
) {
3093 // Unambiguous built-in types.
3100 is_type_comp
= (t1
->typetype
== t2
->typetype
);
3103 is_type_comp
= ( t2
->typetype
==T_OSTR
|| (!is_asn1() && t2
->typetype
==T_ANY
) );
3106 switch (t2
->typetype
) {
3110 case T_UNIVERSALSTRING
:
3111 case T_TELETEXSTRING
:
3112 case T_VIDEOTEXSTRING
:
3113 case T_GRAPHICSTRING
:
3114 case T_OBJECTDESCRIPTOR
:
3115 case T_GENERALSTRING
:
3117 case T_NUMERICSTRING
:
3118 case T_PRINTABLESTRING
:
3120 case T_VISIBLESTRING
:
3122 case T_GENERALIZEDTIME
:
3123 is_type_comp
= true;
3126 is_type_comp
= false;
3130 // Character string group 1.
3133 case T_UNIVERSALSTRING
:
3134 switch (t2
->typetype
) {
3138 case T_UNIVERSALSTRING
:
3140 case T_NUMERICSTRING
:
3141 case T_PRINTABLESTRING
:
3143 case T_VISIBLESTRING
:
3145 case T_GENERALIZEDTIME
:
3146 is_type_comp
= true;
3149 is_type_comp
= false;
3153 // Character string group 2.
3154 case T_TELETEXSTRING
:
3155 case T_VIDEOTEXSTRING
:
3156 case T_GRAPHICSTRING
:
3157 case T_OBJECTDESCRIPTOR
:
3158 case T_GENERALSTRING
:
3159 switch (t2
->typetype
) {
3160 case T_TELETEXSTRING
:
3161 case T_VIDEOTEXSTRING
:
3162 case T_GRAPHICSTRING
:
3163 case T_OBJECTDESCRIPTOR
:
3164 case T_GENERALSTRING
:
3166 case T_NUMERICSTRING
:
3167 case T_PRINTABLESTRING
:
3169 case T_VISIBLESTRING
:
3171 case T_GENERALIZEDTIME
:
3172 is_type_comp
= true;
3175 // Maybe :) is ustr.is_cstr().
3176 is_type_comp
= true;
3179 is_type_comp
= false;
3183 // Character string group 3.
3185 case T_NUMERICSTRING
:
3186 case T_PRINTABLESTRING
:
3188 case T_VISIBLESTRING
:
3190 case T_GENERALIZEDTIME
:
3191 switch (t2
->typetype
) {
3193 case T_NUMERICSTRING
:
3194 case T_PRINTABLESTRING
:
3196 case T_VISIBLESTRING
:
3198 case T_GENERALIZEDTIME
:
3199 is_type_comp
= true;
3202 is_type_comp
= false;
3206 // Polymorphic built-in types.
3209 is_type_comp
= ( t2
->typetype
== T_BSTR
|| t2
->typetype
== T_BSTR_A
);
3213 is_type_comp
= ( t2
->typetype
== T_INT
|| t2
->typetype
== T_INT_A
);
3215 // ROID is visible as OID from TTCN-3.
3217 is_type_comp
= ( t2
->typetype
== T_OID
|| (!is_asn1() && t2
->typetype
== T_ROID
) );
3220 is_type_comp
= ( t2
->typetype
== T_ROID
|| (!p_type
->is_asn1() && t2
->typetype
== T_OID
) );
3223 is_type_comp
= ( t2
->typetype
== T_COMPONENT
&& t1
->u
.component
->is_compatible(t2
->u
.component
) );
3227 is_type_comp
= t1
->is_compatible_record(t2
, p_info
, p_left_chain
, p_right_chain
);
3230 is_type_comp
= t1
->is_compatible_record_of(t2
, p_info
, p_left_chain
, p_right_chain
);
3234 is_type_comp
= t1
->is_compatible_set(t2
, p_info
, p_left_chain
, p_right_chain
);
3237 is_type_comp
= t1
->is_compatible_set_of(t2
, p_info
, p_left_chain
, p_right_chain
);
3240 is_type_comp
= t1
->is_compatible_array(t2
, p_info
, p_left_chain
, p_right_chain
);
3245 is_type_comp
= t1
->is_compatible_choice_anytype(t2
, p_info
, p_left_chain
, p_right_chain
);
3252 is_type_comp
= ( t1
== t2
);
3257 // TODO: Compatibility.
3258 is_type_comp
= ( t1
== t2
);
3261 is_type_comp
= ( t2
->typetype
== T_ANY
|| t2
->typetype
== T_OSTR
);
3264 FATAL_ERROR("Type::is_compatible()");
3266 // if types are compatible then check subtype compatibility
3267 // skip check if p_info is NULL
3268 if ((p_info
!=NULL
) && is_type_comp
&& (sub_type
!=NULL
) && (p_type
->sub_type
!=NULL
) &&
3269 (sub_type
->get_subtypetype()==p_type
->sub_type
->get_subtypetype()))
3271 if (p_info
->get_str1_elem()) {
3272 if (p_info
->get_str2_elem()) {
3273 // both are string elements -> nothing to do
3276 if (!p_type
->sub_type
->is_compatible_with_elem()) {
3277 is_type_comp
= false;
3278 p_info
->set_subtype_error(
3279 string("Subtype mismatch: string element has no common value with subtype ")+
3280 p_type
->sub_type
->to_string());
3284 if (p_info
->get_str2_elem()) {
3286 if (!sub_type
->is_compatible_with_elem()) {
3287 is_type_comp
= false;
3288 p_info
->set_subtype_error(string("Subtype mismatch: subtype ")+
3289 sub_type
->to_string()+string(" has no common value with a string element"));
3292 // string <-> string
3293 if (!sub_type
->is_compatible(p_type
->sub_type
)) {
3294 is_type_comp
= false;
3295 p_info
->set_subtype_error(string("Subtype mismatch: subtype ")+
3296 sub_type
->to_string()+string(" has no common value with subtype ")+
3297 p_type
->sub_type
->to_string());
3302 return is_type_comp
;
3305 bool Type::is_structured_type() const
3324 bool Type::is_subtype_length_compatible(Type
*p_type
)
3326 if (typetype
!= T_SEQOF
&& typetype
!= T_SETOF
)
3327 FATAL_ERROR("Type::is_subtype_length_compatible()");
3328 if (!sub_type
) return true;
3329 SubtypeConstraint::subtype_t st_t
= typetype
== T_SEQOF
?
3330 SubtypeConstraint::ST_RECORDOF
: SubtypeConstraint::ST_SETOF
;
3331 switch (p_type
->typetype
) {
3336 vector
<SubTypeParse
> p_stp_v
;
3337 Value
*p_nof_comps
= new Value(Value::V_INT
,
3338 new int_val_t(p_type
->get_nof_comps()));
3339 p_stp_v
.add(new SubTypeParse(new Ttcn::LengthRestriction(p_nof_comps
)));
3340 SubType
p_st(st_t
, this, NULL
, &p_stp_v
, NULL
);
3344 return sub_type
->is_length_compatible(&p_st
); }
3347 if (!p_type
->sub_type
) return true;
3348 else return sub_type
->is_length_compatible(p_type
->sub_type
);
3350 if (p_type
->u
.array
.dimension
->get_has_error()) return false;
3351 vector
<SubTypeParse
> p_stp_v
;
3353 = new Value(Value::V_INT
,
3354 new int_val_t(p_type
->u
.array
.dimension
->get_size()));
3355 p_stp_v
.add(new SubTypeParse(new Ttcn::LengthRestriction(p_nof_comps
)));
3356 SubType
p_st(st_t
, this, NULL
, &p_stp_v
, NULL
);
3357 p_st
.chk(); // Convert SubTypeParse to SubType.
3360 return sub_type
->is_length_compatible(&p_st
); }
3362 FATAL_ERROR("Type::is_subtype_length_compatible()");
3366 // Errors and warnings are reported in an upper level. We just make a
3367 // simple decision here.
3368 bool Type::is_compatible_record(Type
*p_type
, TypeCompatInfo
*p_info
,
3369 TypeChain
*p_left_chain
,
3370 TypeChain
*p_right_chain
)
3372 if (typetype
!= T_SEQ_A
&& typetype
!= T_SEQ_T
)
3373 FATAL_ERROR("Type::is_compatible_record()");
3374 // The get_type_refd_last() was called for both Types at this point. All
3375 // this code runs in both run-times.
3376 if (this == p_type
) return true;
3377 else if (!use_runtime_2
|| !p_info
3378 || (p_info
&& p_info
->is_strict())) return false;
3379 size_t nof_comps
= get_nof_comps();
3380 switch (p_type
->typetype
) {
3383 // According to 6.3.2.2 the # of fields and the optionality must be
3384 // the same for record types. It's good news for compile-time checks.
3385 // Conversion is always from "p_type -> this".
3386 size_t p_nof_comps
= p_type
->get_nof_comps();
3387 if (nof_comps
!= p_nof_comps
) {
3388 p_info
->set_is_erroneous(this, p_type
, string("The number of fields in "
3389 "record/SEQUENCE types must be the same"));
3392 // If p_info is present we have the chains as well.
3393 if (p_left_chain
->empty()) p_left_chain
->add(this);
3394 if (p_right_chain
->empty()) p_right_chain
->add(p_type
);
3395 for (size_t i
= 0; i
< nof_comps
; i
++) {
3396 CompField
*cf
= get_comp_byIndex(i
);
3397 CompField
*p_cf
= p_type
->get_comp_byIndex(i
);
3398 Type
*cf_type
= cf
->get_type()->get_type_refd_last();
3399 Type
*p_cf_type
= p_cf
->get_type()->get_type_refd_last();
3400 string cf_name
= cf
->get_name().get_dispname();
3401 string p_cf_name
= p_cf
->get_name().get_dispname();
3402 if (cf
->get_is_optional() != p_cf
->get_is_optional()) {
3403 p_info
->append_ref_str(0, "." + cf_name
);
3404 p_info
->append_ref_str(1, "." + p_cf_name
);
3405 p_info
->set_is_erroneous(cf_type
, p_cf_type
, string("The optionality of "
3406 "fields in record/SEQUENCE types must be "
3410 TypeCompatInfo
info_tmp(p_info
->get_my_module(), cf_type
, p_cf_type
,
3412 p_left_chain
->mark_state();
3413 p_right_chain
->mark_state();
3414 p_left_chain
->add(cf_type
);
3415 p_right_chain
->add(p_cf_type
);
3416 if (cf_type
!= p_cf_type
3417 && !(p_left_chain
->has_recursion() && p_right_chain
->has_recursion())
3418 && !cf_type
->is_compatible(p_cf_type
, &info_tmp
, p_left_chain
,
3420 p_info
->append_ref_str(0, "." + cf_name
+ info_tmp
.get_ref_str(0));
3421 p_info
->append_ref_str(1, "." + p_cf_name
+ info_tmp
.get_ref_str(1));
3422 p_info
->set_is_erroneous(info_tmp
.get_type(0), info_tmp
.get_type(1),
3423 info_tmp
.get_error_str());
3424 p_left_chain
->previous_state();
3425 p_right_chain
->previous_state();
3428 p_left_chain
->previous_state();
3429 p_right_chain
->previous_state();
3431 p_info
->set_needs_conversion(true);
3432 p_info
->add_type_conversion(p_type
, this);
3435 if (!p_type
->is_subtype_length_compatible(this)) {
3436 p_info
->set_is_erroneous(this, p_type
, string("Incompatible record of/SEQUENCE "
3442 Type
*p_of_type
= p_type
->get_ofType()->get_type_refd_last();
3443 if (p_type
->typetype
== T_ARRAY
) {
3444 if (p_of_type
->get_typetype() == T_ARRAY
) {
3445 p_info
->set_is_erroneous(this, p_type
, string("record/SEQUENCE types are "
3446 "compatible only with single-dimension "
3450 size_t nof_opt_fields
= 0;
3451 for (size_t i
= 0; i
< nof_comps
; i
++)
3452 if (get_comp_byIndex(i
)->get_is_optional()) nof_opt_fields
++;
3453 if (p_type
->u
.array
.dimension
->get_size()
3454 < nof_comps
- nof_opt_fields
) {
3455 p_info
->set_is_erroneous(this, p_type
, string("The dimension of the array "
3456 "must be >= than the number of mandatory "
3457 "fields in the record/SEQUENCE type"));
3461 if (p_left_chain
->empty()) p_left_chain
->add(this);
3462 if (p_right_chain
->empty()) p_right_chain
->add(p_type
);
3463 for (size_t i
= 0; i
< nof_comps
; i
++) {
3464 Type
*cf_type
= get_comp_byIndex(i
)->get_type()->get_type_refd_last();
3465 TypeCompatInfo
info_tmp(p_info
->get_my_module(), cf_type
, p_of_type
,
3467 p_left_chain
->mark_state();
3468 p_right_chain
->mark_state();
3469 p_left_chain
->add(cf_type
);
3470 p_right_chain
->add(p_of_type
);
3471 if (cf_type
!= p_of_type
3472 && !(p_left_chain
->has_recursion() && p_right_chain
->has_recursion())
3473 && !cf_type
->is_compatible(p_of_type
, &info_tmp
, p_left_chain
,
3475 p_info
->append_ref_str(0, "." + get_comp_byIndex(i
)
3476 ->get_name().get_dispname() + info_tmp
.get_ref_str(0));
3477 p_info
->append_ref_str(1, "[]" + info_tmp
.get_ref_str(1));
3478 p_info
->set_is_erroneous(info_tmp
.get_type(0), info_tmp
.get_type(1),
3479 info_tmp
.get_error_str());
3480 p_left_chain
->previous_state();
3481 p_right_chain
->previous_state();
3484 p_left_chain
->previous_state();
3485 p_right_chain
->previous_state();
3487 p_info
->set_needs_conversion(true);
3488 p_info
->add_type_conversion(p_type
, this);
3493 // 6.3.2.4 makes our job very easy...
3494 p_info
->set_is_erroneous(this, p_type
, string("union/CHOICE/anytype types are "
3495 "compatible only with other "
3496 "union/CHOICE/anytype types"));
3501 // Only set/set of types are compatible with other set/set of types.
3502 // 6.3.2.3 is a little bit unclear about set of types, but we treat them
3503 // this way. Otherwise, it would be possible to use compatibility with
3504 // a "middle-man" set of variable between record/set types:
3505 // type set S { integer f1, integer f2 }
3506 // type record { integer f1, integer f2 }
3507 // type set of integer SO
3508 // var S s := { 1, 2 }
3509 // var R r := { 1, 2 }
3512 // if (r == s) { ... } // Not allowed.
3513 // if (r == so) { ... } // Not allowed. (?)
3514 // Seems to be a fair decision. If we would want compatibility between
3515 // variables of record/set types, we should allow it directly.
3516 p_info
->set_is_erroneous(this, p_type
, string("set/SET and set of/SET OF "
3517 "types are compatible only with other set/SET "
3518 "set of/SET OF types"));
3525 bool Type::is_compatible_record_of(Type
*p_type
, TypeCompatInfo
*p_info
,
3526 TypeChain
*p_left_chain
,
3527 TypeChain
*p_right_chain
)
3529 if (typetype
!= T_SEQOF
) FATAL_ERROR("Type::is_compatible_record_of()");
3530 if (this == p_type
) return true;
3531 else if (!use_runtime_2
|| !p_info
3532 || (p_info
&& p_info
->is_strict())) return false;
3533 switch (p_type
->typetype
) {
3536 if (!is_subtype_length_compatible(p_type
)) {
3537 p_info
->set_is_erroneous(this, p_type
, string("Incompatible "
3538 "record of/SEQUENCE OF subtypes"));
3541 Type
*of_type
= get_ofType()->get_type_refd_last();
3542 if (p_left_chain
->empty()) p_left_chain
->add(this);
3543 if (p_right_chain
->empty()) p_right_chain
->add(p_type
);
3544 for (size_t i
= 0; i
< p_type
->get_nof_comps(); i
++) {
3545 CompField
*p_cf
= p_type
->get_comp_byIndex(i
);
3546 Type
*p_cf_type
= p_cf
->get_type()->get_type_refd_last();
3547 TypeCompatInfo
info_tmp(p_info
->get_my_module(), of_type
, p_cf_type
,
3549 p_left_chain
->mark_state();
3550 p_right_chain
->mark_state();
3551 p_left_chain
->add(of_type
);
3552 p_right_chain
->add(p_cf_type
);
3553 if (of_type
!= p_cf_type
3554 && !(p_left_chain
->has_recursion() && p_right_chain
->has_recursion())
3555 && !of_type
->is_compatible(p_cf_type
, &info_tmp
, p_left_chain
,
3557 p_info
->append_ref_str(0, "[]" + info_tmp
.get_ref_str(0));
3558 p_info
->append_ref_str(1, "." + p_cf
->get_name().get_dispname() +
3559 info_tmp
.get_ref_str(1));
3560 p_info
->set_is_erroneous(info_tmp
.get_type(0),
3561 info_tmp
.get_type(1),
3562 info_tmp
.get_error_str());
3563 p_left_chain
->previous_state();
3564 p_right_chain
->previous_state();
3567 p_left_chain
->previous_state();
3568 p_right_chain
->previous_state();
3570 p_info
->set_needs_conversion(true);
3571 p_info
->add_type_conversion(p_type
, this);
3575 if (!is_subtype_length_compatible(p_type
)) {
3576 p_info
->set_is_erroneous(this, p_type
, string("Incompatible "
3577 "record of/SEQUENCE OF subtypes"));
3580 Type
*of_type
= get_ofType()->get_type_refd_last();
3581 Type
*p_of_type
= p_type
->get_ofType()->get_type_refd_last();
3582 if (p_left_chain
->empty()) p_left_chain
->add(this);
3583 if (p_right_chain
->empty()) p_right_chain
->add(p_type
);
3584 TypeCompatInfo
info_tmp(p_info
->get_my_module(), of_type
, p_of_type
,
3586 p_left_chain
->mark_state();
3587 p_right_chain
->mark_state();
3588 p_left_chain
->add(of_type
);
3589 p_right_chain
->add(p_of_type
);
3590 if (of_type
== p_of_type
3591 || (p_left_chain
->has_recursion() && p_right_chain
->has_recursion())
3592 || of_type
->is_compatible(p_of_type
, &info_tmp
, p_left_chain
,
3594 p_info
->set_needs_conversion(true);
3595 p_info
->add_type_conversion(p_type
, this);
3596 p_left_chain
->previous_state();
3597 p_right_chain
->previous_state();
3600 p_left_chain
->previous_state();
3601 p_right_chain
->previous_state();
3602 p_info
->append_ref_str(0, "[]" + info_tmp
.get_ref_str(0));
3603 // Arrays already have the "[]" in their names.
3604 if (p_type
->get_typetype() != T_ARRAY
) p_info
->append_ref_str(1, string("[]"));
3605 p_info
->append_ref_str(1, info_tmp
.get_ref_str(1));
3606 p_info
->set_is_erroneous(info_tmp
.get_type(0), info_tmp
.get_type(1),
3607 info_tmp
.get_error_str());
3612 p_info
->set_is_erroneous(this, p_type
, string("union/CHOICE/anytype types are "
3613 "compatible only with other "
3614 "union/CHOICE/anytype types"));
3619 p_info
->set_is_erroneous(this, p_type
, string("set/SET and set of/SET OF "
3620 "types are compatible only with other set/SET "
3621 "set of/SET OF types"));
3628 bool Type::is_compatible_array(Type
*p_type
, TypeCompatInfo
*p_info
,
3629 TypeChain
*p_left_chain
,
3630 TypeChain
*p_right_chain
)
3632 if (typetype
!= T_ARRAY
) FATAL_ERROR("Type::is_compatible_array()");
3633 // Copied from the original checker code. The type of the elements and
3634 // the dimension of the array must be the same.
3635 if (this == p_type
) return true;
3636 if (p_type
->typetype
== T_ARRAY
&& u
.array
.element_type
3637 ->is_compatible(p_type
->u
.array
.element_type
, NULL
)
3638 && u
.array
.dimension
->is_identical(p_type
->u
.array
.dimension
))
3640 else if (!use_runtime_2
|| !p_info
3641 || (p_info
&& p_info
->is_strict())) return false;
3642 Type
*of_type
= get_ofType()->get_type_refd_last();
3643 switch (p_type
->get_typetype()) {
3646 if (of_type
->get_typetype() == T_ARRAY
) {
3647 p_info
->set_is_erroneous(this, p_type
, string("record/SEQUENCE types are "
3648 "compatible only with single-dimension "
3652 size_t p_nof_comps
= p_type
->get_nof_comps();
3653 size_t p_nof_opt_fields
= 0;
3654 for (size_t i
= 0; i
< p_nof_comps
; i
++)
3655 if (p_type
->get_comp_byIndex(i
)->get_is_optional())
3657 if (u
.array
.dimension
->get_size() < p_nof_comps
- p_nof_opt_fields
) {
3658 p_info
->set_is_erroneous(this, p_type
, string("The dimension of the array "
3659 "must be >= than the number of mandatory "
3660 "fields in the record/SEQUENCE type"));
3663 if (p_left_chain
->empty()) p_left_chain
->add(this);
3664 if (p_right_chain
->empty()) p_right_chain
->add(p_type
);
3665 for (size_t i
= 0; i
< p_nof_comps
; ++i
) {
3666 CompField
*p_cf
= p_type
->get_comp_byIndex(i
);
3667 Type
*p_cf_type
= p_cf
->get_type()->get_type_refd_last();
3668 string p_cf_name
= p_cf
->get_name().get_dispname();
3669 TypeCompatInfo
info_tmp(p_info
->get_my_module(), of_type
, p_cf_type
,
3671 p_left_chain
->mark_state();
3672 p_right_chain
->mark_state();
3673 p_left_chain
->add(of_type
);
3674 p_right_chain
->add(p_cf_type
);
3675 if (of_type
!= p_cf_type
3676 && !(p_left_chain
->has_recursion() && p_right_chain
->has_recursion())
3677 && !of_type
->is_compatible(p_cf_type
, &info_tmp
, p_left_chain
,
3679 p_info
->append_ref_str(0, info_tmp
.get_ref_str(0));
3680 p_info
->append_ref_str(1, "." + p_cf
->get_name().get_dispname() +
3681 info_tmp
.get_ref_str(1));
3682 p_info
->set_is_erroneous(info_tmp
.get_type(0),
3683 info_tmp
.get_type(1),
3684 info_tmp
.get_error_str());
3685 p_left_chain
->previous_state();
3686 p_right_chain
->previous_state();
3689 p_left_chain
->previous_state();
3690 p_right_chain
->previous_state();
3692 p_info
->set_needs_conversion(true);
3693 p_info
->add_type_conversion(p_type
, this);
3696 if (!p_type
->is_subtype_length_compatible(this)) {
3697 p_info
->set_is_erroneous(this, p_type
, string("Incompatible "
3698 "record of/SEQUENCE OF subtypes"));
3702 if (p_type
->get_typetype() == T_ARRAY
3703 && !u
.array
.dimension
->is_identical(p_type
->u
.array
.dimension
)) {
3704 p_info
->set_is_erroneous(this, p_type
, string("Array types should have "
3705 "the same dimension"));
3708 Type
*p_of_type
= p_type
->get_ofType()->get_type_refd_last();
3709 TypeCompatInfo
info_tmp(p_info
->get_my_module(), of_type
, p_of_type
,
3711 if (p_left_chain
->empty()) p_left_chain
->add(this);
3712 if (p_right_chain
->empty()) p_right_chain
->add(p_type
);
3713 p_left_chain
->mark_state();
3714 p_right_chain
->mark_state();
3715 p_left_chain
->add(of_type
);
3716 p_right_chain
->add(p_of_type
);
3717 if (of_type
== p_of_type
3718 || (p_left_chain
->has_recursion() && p_right_chain
->has_recursion())
3719 || of_type
->is_compatible(p_of_type
, &info_tmp
, p_left_chain
,
3721 p_info
->set_needs_conversion(true);
3722 p_info
->add_type_conversion(p_type
, this);
3723 p_left_chain
->previous_state();
3724 p_right_chain
->previous_state();
3727 p_left_chain
->previous_state();
3728 p_right_chain
->previous_state();
3729 p_info
->append_ref_str(0, info_tmp
.get_ref_str(0));
3730 if (p_type
->get_typetype() != T_ARRAY
) p_info
->append_ref_str(1, string("[]"));
3731 p_info
->append_ref_str(1, info_tmp
.get_ref_str(1));
3732 p_info
->set_is_erroneous(info_tmp
.get_type(0), info_tmp
.get_type(1),
3733 info_tmp
.get_error_str());
3738 p_info
->set_is_erroneous(this, p_type
, string("union/CHOICE/anytype types are "
3739 "compatible only with other "
3740 "union/CHOICE/anytype types"));
3745 p_info
->set_is_erroneous(this, p_type
, string("set/SET and set of/SET OF "
3746 "types are compatible only with other set/SET "
3747 "set of/SET OF types"));
3754 bool Type::is_compatible_set(Type
*p_type
, TypeCompatInfo
*p_info
,
3755 TypeChain
*p_left_chain
,
3756 TypeChain
*p_right_chain
)
3758 if (typetype
!= T_SET_A
&& typetype
!= T_SET_T
)
3759 FATAL_ERROR("Type::is_compatible_set()");
3760 if (this == p_type
) return true;
3761 else if (!use_runtime_2
|| !p_info
3762 || (p_info
&& p_info
->is_strict())) return false;
3763 size_t nof_comps
= get_nof_comps();
3764 switch (p_type
->typetype
) {
3767 // The standard is very generous. We don't need to check for a possible
3768 // combination of compatible fields. According to 6.3.2.3, simply do
3769 // the same thing as for T_SEQ_{A,T} types. The fields are in their
3771 size_t p_nof_comps
= p_type
->get_nof_comps();
3772 if (nof_comps
!= p_nof_comps
) {
3773 p_info
->set_is_erroneous(this, p_type
, string("The number of fields in "
3774 "set/SET types must be the same"));
3777 if (p_left_chain
->empty()) p_left_chain
->add(this);
3778 if (p_right_chain
->empty()) p_right_chain
->add(p_type
);
3779 for (size_t i
= 0; i
< nof_comps
; i
++) {
3780 CompField
*cf
= get_comp_byIndex(i
);
3781 CompField
*p_cf
= p_type
->get_comp_byIndex(i
);
3782 Type
*cf_type
= cf
->get_type()->get_type_refd_last();
3783 Type
*p_cf_type
= p_cf
->get_type()->get_type_refd_last();
3784 string cf_name
= cf
->get_name().get_dispname();
3785 string p_cf_name
= p_cf
->get_name().get_dispname();
3786 if (cf
->get_is_optional() != p_cf
->get_is_optional()) {
3787 p_info
->append_ref_str(0, "." + cf_name
);
3788 p_info
->append_ref_str(1, "." + p_cf_name
);
3789 p_info
->set_is_erroneous(cf_type
, p_cf_type
, string("The optionality of "
3790 "fields in set/SET types must be the "
3794 TypeCompatInfo
info_tmp(p_info
->get_my_module(), cf_type
, p_cf_type
,
3796 p_left_chain
->mark_state();
3797 p_right_chain
->mark_state();
3798 p_left_chain
->add(cf_type
);
3799 p_right_chain
->add(p_cf_type
);
3800 if (cf_type
!= p_cf_type
3801 && !(p_left_chain
->has_recursion() && p_right_chain
->has_recursion())
3802 && !cf_type
->is_compatible(p_cf_type
, &info_tmp
, p_left_chain
,
3804 p_info
->append_ref_str(0, "." + cf_name
+ info_tmp
.get_ref_str(0));
3805 p_info
->append_ref_str(1, "." + p_cf_name
+ info_tmp
.get_ref_str(1));
3806 p_info
->set_is_erroneous(info_tmp
.get_type(0), info_tmp
.get_type(1),
3807 info_tmp
.get_error_str());
3808 p_left_chain
->previous_state();
3809 p_right_chain
->previous_state();
3812 p_left_chain
->previous_state();
3813 p_right_chain
->previous_state();
3815 p_info
->set_needs_conversion(true);
3816 p_info
->add_type_conversion(p_type
, this);
3819 if (!p_type
->is_subtype_length_compatible(this)) {
3820 p_info
->set_is_erroneous(this, p_type
, string("Incompatible set of/SET OF "
3824 if (p_left_chain
->empty()) p_left_chain
->add(this);
3825 if (p_right_chain
->empty()) p_right_chain
->add(p_type
);
3826 Type
*p_of_type
= p_type
->get_ofType()->get_type_refd_last();
3827 for (size_t i
= 0; i
< nof_comps
; i
++) {
3828 Type
*cf_type
= get_comp_byIndex(i
)->get_type()->get_type_refd_last();
3829 TypeCompatInfo
info_tmp(p_info
->get_my_module(), cf_type
, p_of_type
,
3831 p_left_chain
->mark_state();
3832 p_right_chain
->mark_state();
3833 p_left_chain
->add(cf_type
);
3834 p_right_chain
->add(p_of_type
);
3835 if (cf_type
!= p_of_type
3836 && !(p_left_chain
->has_recursion() && p_right_chain
->has_recursion())
3837 && !cf_type
->is_compatible(p_of_type
, &info_tmp
, p_left_chain
,
3839 p_info
->append_ref_str(0, "." + get_comp_byIndex(i
)
3840 ->get_name().get_dispname() + info_tmp
.get_ref_str(0));
3841 p_info
->append_ref_str(1, "[]" + info_tmp
.get_ref_str(1));
3842 p_info
->set_is_erroneous(info_tmp
.get_type(0), info_tmp
.get_type(1),
3843 info_tmp
.get_error_str());
3844 p_left_chain
->previous_state();
3845 p_right_chain
->previous_state();
3848 p_left_chain
->previous_state();
3849 p_right_chain
->previous_state();
3851 p_info
->set_needs_conversion(true);
3852 p_info
->add_type_conversion(p_type
, this);
3857 p_info
->set_is_erroneous(this, p_type
, string("union/CHOICE/anytype types are "
3858 "compatible only with other "
3859 "union/CHOICE/anytype types"));
3865 p_info
->set_is_erroneous(this, p_type
, string("set/SET and set of/SET OF "
3866 "types are compatible only with other set/SET "
3867 "set of/SET OF types"));
3874 bool Type::is_compatible_set_of(Type
*p_type
, TypeCompatInfo
*p_info
,
3875 TypeChain
*p_left_chain
,
3876 TypeChain
*p_right_chain
)
3878 if (typetype
!= T_SETOF
) FATAL_ERROR("Type::is_compatible_set_of()");
3879 if (this == p_type
) return true;
3880 else if (!use_runtime_2
|| !p_info
3881 || (p_info
&& p_info
->is_strict())) return false;
3882 Type
*of_type
= get_ofType();
3883 switch (p_type
->get_typetype()) {
3886 if (!is_subtype_length_compatible(p_type
)) {
3887 p_info
->set_is_erroneous(this, p_type
, string("Incompatible set of/SET OF "
3891 if (p_left_chain
->empty()) p_left_chain
->add(this);
3892 if (p_right_chain
->empty()) p_right_chain
->add(p_type
);
3893 for (size_t i
= 0; i
< p_type
->get_nof_comps(); i
++) {
3894 CompField
*p_cf
= p_type
->get_comp_byIndex(i
);
3895 Type
*p_cf_type
= p_cf
->get_type()->get_type_refd_last();
3896 TypeCompatInfo
info_tmp(p_info
->get_my_module(), of_type
, p_cf_type
,
3898 p_left_chain
->mark_state();
3899 p_right_chain
->mark_state();
3900 p_left_chain
->add(of_type
);
3901 p_right_chain
->add(p_cf_type
);
3902 if (of_type
!= p_cf_type
3903 && !(p_left_chain
->has_recursion() && p_right_chain
->has_recursion())
3904 && !of_type
->is_compatible(p_cf_type
, &info_tmp
, p_left_chain
,
3906 p_info
->append_ref_str(0, "[]" + info_tmp
.get_ref_str(0));
3907 p_info
->append_ref_str(1, "." + p_cf
->get_name().get_dispname() +
3908 info_tmp
.get_ref_str(1));
3909 p_info
->set_is_erroneous(info_tmp
.get_type(0), info_tmp
.get_type(1),
3910 info_tmp
.get_error_str());
3911 p_left_chain
->previous_state();
3912 p_right_chain
->previous_state();
3915 p_left_chain
->previous_state();
3916 p_right_chain
->previous_state();
3918 p_info
->set_needs_conversion(true);
3919 p_info
->add_type_conversion(p_type
, this);
3922 if (!is_subtype_length_compatible(p_type
)) {
3923 p_info
->set_is_erroneous(this, p_type
, string("Incompatible set of/SET OF "
3927 if (p_left_chain
->empty()) p_left_chain
->add(this);
3928 if (p_right_chain
->empty()) p_right_chain
->add(p_type
);
3929 Type
*p_of_type
= p_type
->get_ofType()->get_type_refd_last();
3930 TypeCompatInfo
info_tmp(p_info
->get_my_module(), of_type
, p_of_type
,
3932 p_left_chain
->mark_state();
3933 p_right_chain
->mark_state();
3934 p_left_chain
->add(of_type
);
3935 p_right_chain
->add(p_of_type
);
3936 if (of_type
== p_of_type
3937 || (p_left_chain
->has_recursion() && p_right_chain
->has_recursion())
3938 || of_type
->is_compatible(p_of_type
, &info_tmp
, p_left_chain
,
3940 p_info
->set_needs_conversion(true);
3941 p_info
->add_type_conversion(p_type
, this);
3942 p_left_chain
->previous_state();
3943 p_right_chain
->previous_state();
3946 p_info
->append_ref_str(0, "[]" + info_tmp
.get_ref_str(0));
3947 p_info
->append_ref_str(1, "[]" + info_tmp
.get_ref_str(1));
3948 p_info
->set_is_erroneous(info_tmp
.get_type(0), info_tmp
.get_type(1),
3949 info_tmp
.get_error_str());
3950 p_left_chain
->previous_state();
3951 p_right_chain
->previous_state();
3956 p_info
->set_is_erroneous(this, p_type
, string("union/CHOICE/anytype "
3957 "types are compatible only with other "
3958 "union/CHOICE/anytype types"));
3964 p_info
->set_is_erroneous(this, p_type
, string("set/SET and set of/SET OF "
3965 "types are compatible only with other set/SET "
3966 "set of/SET OF types"));
3973 bool Type::is_compatible_choice_anytype(Type
*p_type
,
3974 TypeCompatInfo
*p_info
,
3975 TypeChain
*p_left_chain
,
3976 TypeChain
*p_right_chain
)
3978 if (typetype
!= T_ANYTYPE
&& typetype
!= T_CHOICE_A
3979 && typetype
!= T_CHOICE_T
)
3980 FATAL_ERROR("Type::is_compatible_choice_anytype()");
3981 if (this == p_type
) return true; // Original "true" leaf...
3982 else if (!use_runtime_2
|| !p_info
3983 || (p_info
&& p_info
->is_strict())) return false; // ...and "false".
3984 if ((typetype
== T_ANYTYPE
&& p_type
->get_typetype() != T_ANYTYPE
)
3985 || (p_type
->get_typetype() == T_ANYTYPE
&& typetype
!= T_ANYTYPE
)) {
3986 p_info
->set_is_erroneous(this, p_type
, string("Type anytype is compatible only "
3987 "with other anytype types"));
3990 switch (p_type
->get_typetype()) {
3998 p_info
->set_is_erroneous(this, p_type
, string("union/CHOICE/anytype types are "
3999 "compatible only with other union/CHOICE/anytype "
4004 if (typetype
!= T_CHOICE_A
&& typetype
!= T_CHOICE_T
) {
4005 p_info
->set_is_erroneous(this, p_type
, string("union/CHOICE types are "
4006 "compatible only with other union/CHOICE "
4012 if (p_left_chain
->empty()) p_left_chain
->add(this);
4013 if (p_right_chain
->empty()) p_right_chain
->add(p_type
);
4014 // Find a field with the same name and with compatible type. There can
4015 // be more alternatives, we need to generate all conversion functions.
4016 // The same field types must be avoided. (For anytypes the "field
4017 // name = module name + field name".)
4018 bool alles_okay
= false;
4019 for (size_t i
= 0; i
< get_nof_comps(); i
++) {
4020 CompField
*cf
= get_comp_byIndex(i
);
4021 Type
*cf_type
= cf
->get_type()->get_type_refd_last();
4022 for (size_t j
= 0; j
< p_type
->get_nof_comps(); ++j
) {
4023 CompField
*p_cf
= p_type
->get_comp_byIndex(j
);
4024 Type
*p_cf_type
= p_cf
->get_type()->get_type_refd_last();
4025 if (cf
->get_name().get_name() != p_cf
->get_name().get_name())
4027 // Don't report errors for each incompatible field, it would be a
4028 // complete mess. Use this temporary for all fields. And forget
4030 TypeCompatInfo
info_tmp(p_info
->get_my_module(), cf_type
, p_cf_type
,
4032 p_left_chain
->mark_state();
4033 p_right_chain
->mark_state();
4034 p_left_chain
->add(cf_type
);
4035 p_right_chain
->add(p_cf_type
);
4036 if (cf_type
== p_cf_type
4037 || (p_left_chain
->has_recursion() && p_right_chain
->has_recursion())
4038 || cf_type
->is_compatible(p_cf_type
, &info_tmp
, p_left_chain
,
4040 if (cf_type
!= p_cf_type
&& cf_type
->is_structured_type()
4041 && p_cf_type
->is_structured_type()) {
4042 if (typetype
== T_ANYTYPE
&& cf_type
->get_my_scope()
4043 ->get_scope_mod() != p_cf_type
->get_my_scope()
4044 ->get_scope_mod()) {
4045 p_left_chain
->previous_state();
4046 p_right_chain
->previous_state();
4049 p_info
->add_type_conversion(p_cf_type
, cf_type
);
4053 p_left_chain
->previous_state();
4054 p_right_chain
->previous_state();
4058 p_info
->set_needs_conversion(true);
4059 p_info
->add_type_conversion(p_type
, this);
4062 p_info
->set_is_erroneous(this, p_type
, string("No compatible "
4063 "union/CHOICE/anytype field found"));
4071 /** \todo consider subtype constraints */
4072 bool Type::is_identical(Type
*p_type
)
4076 Type
*t1
= get_type_refd_last();
4077 Type
*t2
= p_type
->get_type_refd_last();
4078 if (t2
->typetype
== T_ERROR
) return true;
4079 switch (t1
->typetype
) {
4081 // error type is identical to everything
4101 // user-defined structured types must be identical
4104 // the embedded type and the dimension must be identical in case of arrays
4105 return t2
->typetype
== T_ARRAY
&&
4106 t1
->u
.array
.element_type
->is_identical(t2
->u
.array
.element_type
) &&
4107 t1
->u
.array
.dimension
->is_identical(t2
->u
.array
.dimension
);
4109 // in case of built-in types the TTCN-3 view of typetype must be the same
4110 return get_typetype_ttcn3(t1
->typetype
) ==
4111 get_typetype_ttcn3(t2
->typetype
);
4115 void Type::tr_compsof(ReferenceChain
*refch
)
4117 if (typetype
!=T_SEQ_A
&& typetype
!=T_SET_A
)
4118 FATAL_ERROR("Type::tr_compsof()");
4119 if (u
.secho
.tr_compsof_ready
) return;
4120 if (u
.secho
.block
) parse_block_Se();
4121 bool auto_tagging
=u
.secho
.ctss
->needs_auto_tags();
4123 refch
->mark_state();
4124 if (refch
->add(get_fullname())) u
.secho
.ctss
->tr_compsof(refch
, false);
4125 refch
->prev_state();
4126 u
.secho
.tr_compsof_ready
= true;
4127 u
.secho
.ctss
->tr_compsof(0, true);
4129 ReferenceChain
refch2(this, "While resolving COMPONENTS OF");
4130 refch2
.add(get_fullname());
4131 Error_Context
cntxt(this, "While resolving COMPONENTS OF");
4132 u
.secho
.ctss
->tr_compsof(&refch2
, false);
4133 u
.secho
.tr_compsof_ready
= true;
4134 u
.secho
.ctss
->tr_compsof(0, true);
4136 if(auto_tagging
) u
.secho
.ctss
->add_auto_tags();
4139 bool Type::is_startable()
4141 if(typetype
!= T_FUNCTION
)
4142 FATAL_ERROR("Type::is_startable()");
4144 return u
.fatref
.is_startable
;
4147 bool Type::is_list_type(bool allow_array
)
4149 switch (get_type_refd_last()->get_typetype_ttcn3()) {
4165 void Type::chk_coding(bool encode
) {
4166 string
& coding_str
= encode
? encoding_str
: decoding_str
;
4167 if (!coding_str
.empty())
4169 coding_by_function
= false;
4171 if (!w_attrib_path
) {
4172 error("No coding rule specified for type '%s'", get_typename().c_str());
4175 Type::MessageEncodingType_t coding
= CT_UNDEF
;
4177 // Checking extension attributes
4178 Ttcn::ExtensionAttributes
* extatrs
= parse_extattributes(w_attrib_path
);
4179 if (extatrs
!= 0) { // NULL means parsing error
4180 for (size_t k
= 0; k
< extatrs
->size(); ++k
) {
4181 Ttcn::ExtensionAttribute
&ea
= extatrs
->get(k
);
4182 Ttcn::TypeMappings
*inmaps
= 0, *maps
= 0;
4183 Ttcn::TypeMapping
* mapping
= 0;
4184 Ttcn::TypeMappingTarget
* target
= 0;
4186 switch (ea
.get_type()) {
4187 case Ttcn::ExtensionAttribute::ENCDECVALUE
:
4188 ea
.get_encdecvalue_mappings(inmaps
, maps
);
4189 maps
= encode
? maps
: inmaps
;
4190 maps
->set_my_scope(this->get_my_scope());
4192 // look for coding settings
4193 t
= encode
? this : Type::get_pooltype(T_BSTR
);
4194 mapping
= maps
->get_mapping_byType(t
);
4195 if (mapping
->get_nof_targets() == 0)
4198 for (size_t ind
= 0; ind
< mapping
->get_nof_targets(); ind
++) {
4199 target
= mapping
->get_target_byIndex(ind
);
4200 t
= target
->get_target_type();
4201 if ((encode
&& (t
->get_typetype() == T_BSTR
)) ||
4202 (!encode
&& (t
->get_typename() == this->get_typename())))
4204 if (target
->get_mapping_type() ==
4205 Ttcn::TypeMappingTarget::TM_FUNCTION
) {
4206 if (!coding_str
.empty())
4207 target
->error("Multiple definition of this target");
4208 coding_str
= target
->get_function()->
4209 get_genname_from_scope(my_scope
);
4210 coding_by_function
= true;
4212 target
->error("Only function is supported to do this mapping");
4216 if (coding_str
.empty()) {
4217 ea
.warning("Extension attribute is found for %s but without "
4218 "typemappings", encode
? "encvalue" : "decvalue");
4223 case Ttcn::ExtensionAttribute::ANYTYPELIST
:
4224 break; // ignore (may be inherited from the module)
4226 case Ttcn::ExtensionAttribute::NONE
:
4227 break; // ignore erroneous attribute
4230 ea
.error("A type can only have type mapping extension attribute: "
4231 "in(...) or out(...)");
4238 if (!coding_str
.empty())
4242 const vector
<SingleWithAttrib
>& real_attribs
4243 = w_attrib_path
->get_real_attrib();
4245 for (size_t i
= real_attribs
.size(); i
> 0 && !found
; i
--) {
4246 if (real_attribs
[i
-1]->get_attribKeyword()
4247 == SingleWithAttrib::AT_ENCODE
) {
4249 coding
= get_enc_type(*real_attribs
[i
-1]);
4250 if (coding
== CT_UNDEF
) {
4251 // "encode" attribute found, but the spec didn't match any known encodings
4252 error("Unknown encoding '%s'", real_attribs
[i
-1]->get_attribSpec().get_spec().c_str());
4257 if (coding
== CT_UNDEF
) {
4258 // no "encode" attribute found
4259 error("No coding rule specified for type '%s'", get_typename().c_str());
4262 if (!has_encoding(coding
)) {
4263 error("Type '%s' cannot be coded with the selected method '%s'",
4264 get_typename().c_str(),
4265 get_encoding_name(coding
));
4273 coding_str
= "TEXT";
4279 coding_str
= "XER, XER_EXTENDED"; // TODO: fine tuning this parameter
4282 coding_str
= "JSON";
4285 coding_str
= "BER, ";
4286 BerAST
* ber
= berattrib
;
4287 if (!ber
) // use default settings if attributes are not specified
4290 coding_str
+= ber
->get_encode_str();
4292 coding_str
+= ber
->get_decode_str();
4297 error("Unknown coding selected for type '%s'", get_typename().c_str());
4300 coding_by_function
= false;
4303 bool Type::is_coding_by_function() const {
4304 return coding_by_function
;
4307 const string
& Type::get_coding(bool encode
) const {
4309 return encoding_str
;
4311 return decoding_str
;
4314 namespace { // unnamed
4315 const string
ex_emm_ell("XML"), ex_ee_arr("XER");
4318 Type::MessageEncodingType_t
Type::get_enc_type(const SingleWithAttrib
& atr
) {
4319 const string
& enc
= atr
.get_attribSpec().get_spec();
4322 else if (enc
== "TEXT")
4324 else if (enc
== "JSON")
4326 else if (enc
== "BER:2002" || enc
== "CER:2002" || enc
== "DER:2002")
4328 else if (enc
== ex_emm_ell
)
4330 else if (enc
== ex_ee_arr
) {
4331 atr
.warning("The correct name of the encoding is ''XML''");
4334 else if (enc
== "PER")
4339 bool Type::has_ei_withName(const Identifier
& p_id
) const
4347 FATAL_ERROR("Type::has_ei_withName()");
4349 return u
.enums
.eis
->has_ei_withName(p_id
);
4352 EnumItem
*Type::get_ei_byName(const Identifier
& p_id
) const
4360 FATAL_ERROR("Type::get_ei_byName()");
4362 return u
.enums
.eis
->get_ei_byName(p_id
);
4365 EnumItem
*Type::get_ei_byIndex(size_t n
) const
4373 FATAL_ERROR("Type::get_ei_byIndex()");
4375 return u
.enums
.eis
->get_ei_byIndex(n
);
4378 size_t Type::get_nof_comps()
4386 return u
.secho
.cfm
->get_nof_comps();
4389 if(u
.secho
.block
) parse_block_Se();
4390 return u
.secho
.ctss
->get_nof_comps();
4392 if(u
.secho
.block
) parse_block_Choice();
4393 return u
.secho
.ctss
->get_nof_comps();
4395 return u
.array
.dimension
->get_size();
4397 if (u
.signature
.parameters
)
4398 return u
.signature
.parameters
->get_nof_params();
4401 FATAL_ERROR("Type::get_nof_comps(%d)", typetype
);
4406 const Identifier
& Type::get_comp_id_byIndex(size_t n
)
4414 return u
.secho
.cfm
->get_comp_byIndex(n
)->get_name();
4417 if(u
.secho
.block
) parse_block_Se();
4418 return u
.secho
.ctss
->get_comp_byIndex(n
)->get_name();
4420 if(u
.secho
.block
) parse_block_Choice();
4421 return u
.secho
.ctss
->get_comp_byIndex(n
)->get_name();
4423 return u
.signature
.parameters
->get_param_byIndex(n
)->get_id();
4425 FATAL_ERROR("Type::get_comp_id_byIndex()");
4427 // to avoid warnings
4428 const Identifier
*fake
= 0;
4432 CompField
* Type::get_comp_byIndex(size_t n
)
4440 return u
.secho
.cfm
->get_comp_byIndex(n
);
4443 if(u
.secho
.block
) parse_block_Se();
4444 return u
.secho
.ctss
->get_comp_byIndex(n
);
4446 if(u
.secho
.block
) parse_block_Choice();
4447 return u
.secho
.ctss
->get_comp_byIndex(n
);
4449 FATAL_ERROR("Type::get_comp_byIndex()");
4454 size_t Type::get_comp_index_byName(const Identifier
& p_name
)
4456 Type
*t
= get_type_refd_last();
4458 FATAL_ERROR("Type::get_comp_index_byName()");
4459 if (!t
->u
.secho
.field_by_name
) {
4460 t
->u
.secho
.field_by_name
= new map
<string
, size_t>;
4461 size_t nof_comps
= t
->get_nof_comps();
4462 for (size_t i
= 0; i
< nof_comps
; i
++) {
4463 const string
& field_name
=
4464 t
->get_comp_byIndex(i
)->get_name().get_name();
4465 if (!t
->u
.secho
.field_by_name
->has_key(field_name
))
4466 t
->u
.secho
.field_by_name
->add(field_name
, new size_t(i
));
4469 return *(*t
->u
.secho
.field_by_name
)[p_name
.get_name()];
4472 size_t Type::get_eis_index_byName(const Identifier
& p_name
)
4474 Type
*t
= get_type_refd_last();
4475 switch (t
->typetype
) {
4480 FATAL_ERROR("Type::get_eis_index_byName()");
4482 if (!t
->u
.enums
.eis_by_name
) {
4483 t
->u
.enums
.eis_by_name
= new map
<string
, size_t>;
4484 size_t nof_eis
= t
->u
.enums
.eis
->get_nof_eis();
4485 for (size_t i
= 0; i
< nof_eis
; i
++) {
4486 const string
& enum_name
=
4487 t
->u
.enums
.eis
->get_ei_byIndex(i
)->get_name().get_name();
4488 if (!t
->u
.enums
.eis_by_name
->has_key(enum_name
))
4489 t
->u
.enums
.eis_by_name
->add(enum_name
, new size_t(i
));
4492 return *(*t
->u
.enums
.eis_by_name
)[p_name
.get_name()];
4495 const Int
& Type::get_enum_val_byId(const Identifier
& p_name
)
4497 if(!checked
) FATAL_ERROR("Type::get_enum_val_byId(): Not checked.");
4503 FATAL_ERROR("Type::get_enum_val_byId()");
4505 return u
.enums
.eis
->get_ei_byName(p_name
)->get_value()
4506 ->get_value_refd_last()->get_val_Int()->get_val();
4509 size_t Type::get_nof_root_comps()
4514 if(u
.secho
.block
) parse_block_Se();
4515 return u
.secho
.ctss
->get_nof_root_comps();
4518 FATAL_ERROR("Type::get_nof_root_comps()");
4523 CompField
* Type::get_root_comp_byIndex(size_t n
)
4528 if(u
.secho
.block
) parse_block_Se();
4529 return u
.secho
.ctss
->get_root_comp_byIndex(n
);
4532 FATAL_ERROR("Type::get_root_comp_byIndex()");
4537 bool Type::has_comp_withName(const Identifier
& p_name
)
4539 Type
*t
= get_type_refd_last();
4540 switch (t
->typetype
) {
4546 return t
->u
.secho
.cfm
->has_comp_withName(p_name
);
4549 if (t
->u
.secho
.block
) t
->parse_block_Se();
4550 return t
->u
.secho
.ctss
->has_comp_withName(p_name
);
4552 if (t
->u
.secho
.block
) t
->parse_block_Choice();
4553 return t
->u
.secho
.ctss
->has_comp_withName(p_name
);
4555 if (t
->u
.signature
.parameters
)
4556 return t
->u
.signature
.parameters
->has_param_withName(p_name
);
4559 FATAL_ERROR("Type::has_comp_withName()");
4564 CompField
* Type::get_comp_byName(const Identifier
& p_name
)
4566 Type
*t
= get_type_refd_last();
4567 switch (t
->typetype
) {
4573 return t
->u
.secho
.cfm
->get_comp_byName(p_name
);
4576 if (t
->u
.secho
.block
) t
->parse_block_Se();
4577 return t
->u
.secho
.ctss
->get_comp_byName(p_name
);
4579 if(t
->u
.secho
.block
) t
->parse_block_Choice();
4580 return t
->u
.secho
.ctss
->get_comp_byName(p_name
);
4582 FATAL_ERROR("Type::get_comp_byName()");
4587 void Type::add_comp(CompField
*p_cf
)
4595 u
.secho
.cfm
->add_comp(p_cf
);
4598 FATAL_ERROR("Type::add_comp()");
4602 Type
*Type::get_ofType()
4604 Type
*t
=get_type_refd_last();
4605 switch (t
->typetype
) {
4608 return t
->u
.seof
.ofType
;
4610 return t
->u
.array
.element_type
;
4612 FATAL_ERROR("Type::get_ofType()");
4617 OC_defn
* Type::get_my_oc()
4621 return u
.ref
.oc_defn
;
4624 return u
.secho
.oc_defn
;
4627 FATAL_ERROR("Type::get_my_oc()");
4632 const Identifier
& Type::get_oc_fieldname()
4636 return *u
.ref
.oc_fieldname
;
4639 return *u
.secho
.oc_fieldname
;
4642 FATAL_ERROR("Type::get_oc_fieldname()");
4643 // to avoid warning...
4644 return *u
.secho
.oc_fieldname
;
4648 void Type::set_my_tableconstraint(const TableConstraint
*p_tc
)
4652 u
.secho
.my_tableconstraint
=p_tc
;
4655 FATAL_ERROR("Type::set_my_tableconstraint()");
4659 const TableConstraint
* Type::get_my_tableconstraint()
4663 return u
.secho
.my_tableconstraint
;
4666 FATAL_ERROR("Type::get_my_tableconstraint()");
4671 Ttcn::ArrayDimension
*Type::get_dimension() const
4673 if (typetype
!= T_ARRAY
) FATAL_ERROR("Type::get_dimension()");
4674 return u
.array
.dimension
;
4677 Ttcn::PortTypeBody
*Type::get_PortBody() const
4679 if (typetype
!= T_PORT
) FATAL_ERROR("Type::get_PortBody()");
4683 ComponentTypeBody
*Type::get_CompBody() const
4685 if (typetype
!= T_COMPONENT
) FATAL_ERROR("Type::get_CompBody()");
4689 SignatureParamList
*Type::get_signature_parameters() const
4691 if (typetype
!= T_SIGNATURE
|| !checked
)
4692 FATAL_ERROR("Type::get_signature_parameters()");
4693 return u
.signature
.parameters
;
4696 SignatureExceptions
*Type::get_signature_exceptions() const
4698 if (typetype
!= T_SIGNATURE
|| !checked
)
4699 FATAL_ERROR("Type::get_signature_exceptions()");
4700 return u
.signature
.exceptions
;
4703 Type
*Type::get_signature_return_type() const
4705 if (typetype
!= T_SIGNATURE
|| !checked
)
4706 FATAL_ERROR("Type::get_signature_return_type()");
4707 return u
.signature
.return_type
;
4710 bool Type::is_nonblocking_signature() const
4712 if (typetype
!= T_SIGNATURE
|| !checked
)
4713 FATAL_ERROR("Type::is_nonblocking_signature()");
4714 return u
.signature
.no_block
;
4717 Ttcn::FormalParList
*Type::get_fat_parameters()
4719 if(!checked
) FATAL_ERROR("Type::get_fat_parameteres()");
4724 return u
.fatref
.fp_list
;
4726 FATAL_ERROR("Type::get_fat_parameteres()");
4731 Type
*Type::get_function_return_type()
4733 if(!checked
) FATAL_ERROR("Type::get_function_return_type()");
4736 return u
.fatref
.return_type
;
4738 FATAL_ERROR("Type::get_function_return_type()");
4743 Type
*Type::get_fat_runs_on_type()
4745 if(!checked
) FATAL_ERROR("Type::get_fat_runs_on_type()");
4750 return u
.fatref
.runs_on
.type
;
4752 FATAL_ERROR("Type::get_fat_runs_on_type()");
4757 bool Type::get_fat_runs_on_self()
4759 if(!checked
) FATAL_ERROR("Type::get_fat_runs_on_self()");
4764 return u
.fatref
.runs_on
.self
;
4766 FATAL_ERROR("Type::get_fat_runs_on_self()");
4771 bool Type::get_returns_template()
4773 if (!checked
|| typetype
!= T_FUNCTION
)
4774 FATAL_ERROR("Type::Returns_template()");
4775 return u
.fatref
.returns_template
;
4778 void Type::add_tag(Tag
*p_tag
)
4780 if(!tags
) tags
=new Tags();
4781 tags
->add_tag(p_tag
);
4784 void Type::add_constraints(Constraints
*p_constraints
)
4786 if(!p_constraints
) return;
4788 FATAL_ERROR("This type already has its constraints");
4789 constraints
=p_constraints
;
4790 constraints
->set_my_type(this);
4793 Reference
* Type::get_Reference()
4798 void Type::chk_table_constraints()
4800 if(!tbl_cons_checked
) {
4801 tbl_cons_checked
=true;
4802 if (constraints
) constraints
->chk_table();
4811 for(size_t i
=0; i
<get_nof_comps(); i
++)
4812 get_comp_byIndex(i
)->get_type()->chk_table_constraints();
4816 u
.seof
.ofType
->chk_table_constraints();
4824 void Type::check_subtype_constraints()
4826 if (sub_type
!=NULL
) FATAL_ERROR("Type::check_subtype_constraints()");
4828 // get parent subtype or NULL if it doesn't exist
4829 SubType
* parent_subtype
= NULL
;
4830 if (is_ref()) parent_subtype
= get_type_refd()->sub_type
;
4832 // if the parent subtype is erroneous then ignore it, the error was already
4834 if ( (parent_subtype
!=NULL
) &&
4835 (parent_subtype
->get_subtypetype()==SubtypeConstraint::ST_ERROR
) )
4836 parent_subtype
= NULL
;
4838 // return if there are neither inherited nor own constraints
4839 if ( (parent_subtype
==NULL
) && (parsed_restr
==NULL
) && (constraints
==NULL
)
4840 && (SubtypeConstraint::get_asn_type_constraint(this)==NULL
) ) return;
4842 // the subtype type is determined by the type of this type
4843 if (get_type_refd_last()->get_typetype()==T_ERROR
) return;
4844 SubtypeConstraint::subtype_t s_t
= get_subtype_type();
4845 if (s_t
==SubtypeConstraint::ST_ERROR
) {
4846 error("Subtype constraints are not applicable to type `%s'",
4847 get_typename().c_str());
4851 // create the aggregate subtype for this type
4852 sub_type
= new SubType(s_t
, this, parent_subtype
, parsed_restr
, constraints
);
4856 bool Type::has_multiple_tags()
4858 if (tags
) return false;
4867 return get_type_refd()->has_multiple_tags();
4873 Tag
*Type::get_tag()
4876 Tag
*tag
=tags
->get_tag_byIndex(tags
->get_nof_tags()-1);
4880 else return get_default_tag();
4883 void Type::get_tags(TagCollection
& coll
, map
<Type
*, void>& chain
)
4885 if(typetype
!=T_CHOICE_A
)
4886 FATAL_ERROR("Type::get_tags()");
4887 if (chain
.has_key(this)) return;
4889 if(u
.secho
.block
) parse_block_Choice();
4890 size_t n_alts
= u
.secho
.ctss
->get_nof_comps();
4891 for(size_t i
=0; i
<n_alts
; i
++) {
4892 CompField
*cf
= u
.secho
.ctss
->get_comp_byIndex(i
);
4893 Type
*type
= cf
->get_type();
4894 if(type
->has_multiple_tags()) {
4895 type
=type
->get_type_refd_last();
4896 type
->get_tags(coll
, chain
);
4899 const Tag
*tag
=type
->get_tag();
4900 if(coll
.hasTag(tag
))
4901 error("Alternative `%s' in CHOICE has non-distinct tag",
4902 cf
->get_name().get_dispname().c_str());
4903 else coll
.addTag(tag
);
4906 if(u
.secho
.ctss
->has_ellipsis()) coll
.setExtensible();
4909 Tag
*Type::get_smallest_tag()
4911 if(!has_multiple_tags()) return get_tag()->clone();
4912 Type
*t
=get_type_refd_last();
4913 TagCollection tagcoll
;
4914 map
<Type
*, void> chain
;
4915 t
->get_tags(tagcoll
, chain
);
4917 return tagcoll
.getSmallestTag()->clone();
4920 bool Type::needs_explicit_tag()
4929 if(!dynamic_cast<Asn::Ref_pard
*>(u
.ref
.ref
)) {
4930 Scope
*s
=u
.ref
.ref
->get_refd_assignment()->get_my_scope();
4931 if(s
->get_parent_scope()!=s
->get_scope_mod()) {
4932 // Not in the module scope, so it is a dummyreference (X.680
4935 WARNING("%s is a dummyreference, i give him an explicit tag :)",
4936 get_fullname().c_str());
4937 WARNING("0: %s", s->get_scope_name().c_str());
4938 WARNING("1: %s", s->get_parent_scope()->get_scope_name().c_str());
4939 WARNING("2: %s", s->get_scope_mod()->get_scope_name().c_str());
4949 Type
*t
= get_type_refd();
4950 if(t
->is_tagged()) return false;
4951 else return t
->needs_explicit_tag();
4954 // T_ANYTYPE probably does not need explicit tagging
4959 void Type::cut_auto_tags()
4962 tags
->cut_auto_tags();
4963 if (tags
->get_nof_tags() == 0) {
4971 * I suppose in this function that tags->chk() and
4972 * tags->set_plicit() are already done.
4974 Tags
* Type::build_tags_joined(Tags
*p_tags
)
4976 if(!p_tags
) p_tags
=new Tags();
4983 get_type_refd()->build_tags_joined(p_tags
);
4987 //TODO case T_ANYTYPE: for build_tags_joined ?
4992 p_tags
->add_tag(get_default_tag()->clone());
4996 for(size_t i
=0; i
<tags
->get_nof_tags(); i
++) {
4997 Tag
*tag
=tags
->get_tag_byIndex(i
);
4998 switch(tag
->get_plicit()) {
4999 case Tag::TAG_EXPLICIT
:
5000 p_tags
->add_tag(tag
->clone());
5002 case Tag::TAG_IMPLICIT
: {
5003 Tag
*t_p_tag
=p_tags
->get_tag_byIndex(p_tags
->get_nof_tags()-1);
5004 t_p_tag
->set_tagclass(tag
->get_tagclass());
5005 t_p_tag
->set_tagvalue(tag
->get_tagvalue());
5008 FATAL_ERROR("Type::build_tags_joined()");
5015 void Type::set_with_attr(Ttcn::MultiWithAttrib
* p_attrib
)
5019 w_attrib_path
= new WithAttribPath();
5022 w_attrib_path
->set_with_attr(p_attrib
);
5025 void Type::set_parent_path(WithAttribPath
* p_path
)
5029 w_attrib_path
= new WithAttribPath();
5031 w_attrib_path
->set_parent(p_path
);
5032 if (typetype
== T_COMPONENT
)
5033 u
.component
->set_parent_path(w_attrib_path
);
5036 WithAttribPath
* Type::get_attrib_path() const
5038 return w_attrib_path
;
5041 bool Type::hasRawAttrs()
5043 if(rawattrib
) return true;
5047 if(w_attrib_path
->get_had_global_variants()) return true;
5049 vector
<SingleWithAttrib
> const &real_attribs
5050 = w_attrib_path
->get_real_attrib();
5052 for (size_t i
= 0; i
< real_attribs
.size(); i
++)
5053 if (real_attribs
[i
]->get_attribKeyword()
5054 == SingleWithAttrib::AT_VARIANT
)
5059 MultiWithAttrib
* temp_attrib
= w_attrib_path
->get_with_attr();
5061 for(size_t i
= 0; i
< temp_attrib
->get_nof_elements(); i
++)
5062 if(temp_attrib
->get_element(i
)->get_attribKeyword()
5063 == SingleWithAttrib::AT_VARIANT
5064 && (!temp_attrib
->get_element(i
)->get_attribQualifiers()
5065 || temp_attrib
->get_element(i
)->get_attribQualifiers()
5066 ->get_nof_qualifiers() == 0))
5068 w_attrib_path
->set_had_global_variants( true );
5076 bool Type::hasNeedofRawAttrs()
5078 if(rawattrib
) return true;
5085 nof_comps
= get_nof_comps();
5086 for(size_t i
=0; i
< nof_comps
; i
++)
5088 if(get_comp_byIndex(i
)->get_type()->hasNeedofRawAttrs())
5100 bool Type::hasNeedofTextAttrs()
5102 if(textattrib
) return true;
5109 nof_comps
= get_nof_comps();
5110 for(size_t i
=0; i
< nof_comps
; i
++)
5112 if(get_comp_byIndex(i
)->get_type()->hasNeedofTextAttrs())
5124 bool Type::hasNeedofJsonAttrs()
5126 if(jsonattrib
) return true;
5133 nof_comps
= get_nof_comps();
5134 for (size_t i
= 0; i
< nof_comps
; ++i
)
5136 if (get_comp_byIndex(i
)->get_type()->hasNeedofJsonAttrs())
5148 bool Type::hasNeedofXerAttrs()
5150 if(xerattrib
&& !xerattrib
->empty()) return true;
5157 nof_comps
= get_nof_comps();
5158 for(size_t i
=0; i
< nof_comps
; i
++)
5160 if(get_comp_byIndex(i
)->get_type()->hasNeedofXerAttrs())
5172 bool Type::hasVariantAttrs()
5176 if(w_attrib_path
->get_had_global_variants()) return true;
5178 vector
<SingleWithAttrib
> const &real_attribs
5179 = w_attrib_path
->get_real_attrib();
5181 for (size_t i
= 0; i
< real_attribs
.size(); i
++)
5182 if (real_attribs
[i
]->get_attribKeyword()
5183 == SingleWithAttrib::AT_VARIANT
)
5188 MultiWithAttrib
* temp_attrib
= w_attrib_path
->get_with_attr();
5190 for(size_t i
= 0; i
< temp_attrib
->get_nof_elements(); i
++)
5191 if(temp_attrib
->get_element(i
)->get_attribKeyword()
5192 == SingleWithAttrib::AT_VARIANT
5193 && (!temp_attrib
->get_element(i
)->get_attribQualifiers()
5194 || temp_attrib
->get_element(i
)->get_attribQualifiers()
5195 ->get_nof_qualifiers() != 0))
5197 w_attrib_path
->set_had_global_variants( true );
5205 bool Type::hasEncodeAttr(const MessageEncodingType_t encoding_type
)
5207 if (CT_JSON
== encoding_type
&&
5208 (is_asn1() || (is_ref() && get_type_refd()->is_asn1()))) {
5209 // ASN.1 types automatically support JSON encoding
5212 // Check the type itself first, then the root type
5213 WithAttribPath
*aps
[2] = { 0, 0 };
5214 size_t num_aps
= ((aps
[0] = get_attrib_path()) != 0);
5215 // assign, compare, then add 0 or 1
5217 num_aps
+= ((aps
[num_aps
] = get_type_refd()->get_attrib_path()) != 0);
5219 for (size_t a
= 0; a
< num_aps
; ++a
) {
5220 const vector
<SingleWithAttrib
>& real
= aps
[a
]->get_real_attrib();
5221 const size_t num_atr
= real
.size();
5222 for (size_t i
= 0; i
< num_atr
; ++i
) {
5223 const SingleWithAttrib
& s
= *real
[i
];
5224 if (s
.get_attribKeyword() == SingleWithAttrib::AT_ENCODE
) {
5225 const string
& spec
= s
.get_attribSpec().get_spec();
5226 if (spec
== get_encoding_name(encoding_type
)) {
5229 // if it has an encode other than the one we're looking for, quit now
5238 namespace { // unnamed
5240 enum state
{ PROCESSING
= -1, ANSWER_NO
, ANSWER_YES
};
5242 struct memoizer
: private map
<Type
*, state
> {
5243 memoizer() : map
<Type
*, state
>() {}
5246 for (int i
= size()-1; i
>= 0; --i
) {
5247 delete get_nth_elem(i
);
5252 bool remember (Type
*t
, state s
) {
5257 add(t
, new state(s
));
5259 return s
== ANSWER_YES
;
5262 bool has_key(Type
*t
) {
5263 return map
<Type
*, state
>::has_key(t
);
5266 state
* get(Type
*t
) {
5267 return operator [](t
);
5273 bool Type::has_encoding(MessageEncodingType_t encoding_type
)
5275 static memoizer memory
;
5276 static memoizer json_mem
;
5278 switch (encoding_type
) {
5282 if (t
->is_asn1()) return true;
5283 else if (t
->is_ref()) t
= t
->get_type_refd();
5285 switch (t
->typetype
) {
5293 // these basic TTCN-3 types have ASN.1 equivalents
5302 if (memory
.has_key(this)) {
5303 state
*s
= memory
.get(this);
5315 // For ASN.1 types, the answer depends solely on the -a switch.
5316 // They are all considered to have Basic (i.e. useless) XER,
5317 // unless the -a switch says removes XER from all ASN.1 types.
5318 if (t
->is_asn1()) return memory
.remember(t
,
5319 asn1_xer
? ANSWER_YES
: ANSWER_NO
);
5320 else if (t
->is_ref()) t
= t
->get_type_refd();
5321 else { // at the end of the ref. chain
5322 switch (t
->typetype
) {
5328 // The octetstring type can always be encoded in XER.
5329 // XSD:base64Binary is only needed for Type::is_charenc()
5331 case T_HSTR
: // TTCN-3 hexstring
5332 case T_VERDICT
: // TTCN-3 verdict
5333 case T_CSTR
: // TTCN3 charstring
5334 case T_USTR
: // TTCN3 universal charstring
5335 return memory
.remember(t
, ANSWER_YES
);
5338 break; // the switch; skip to checking if it has encode "XML";
5340 case T_PORT
: // TTCN-3 port (the list of in's, out's, inout's)
5341 case T_COMPONENT
: // TTCN-3 comp. type (extends, and { ... })
5342 case T_DEFAULT
: // TTCN-3
5343 case T_SIGNATURE
: // TTCN-3
5344 case T_FUNCTION
: // TTCN-3
5345 case T_ALTSTEP
: // TTCN-3
5346 case T_TESTCASE
: // TTCN-3
5347 case T_ANYTYPE
: // TTCN-3 anytype
5348 return memory
.remember(t
, ANSWER_NO
);
5353 return false; // why don't we remember these ?
5358 // No field may reject XER
5359 size_t ncomp
= t
->get_nof_comps();
5360 for (size_t i
= 0; i
< ncomp
; ++i
) {
5361 Type
*t2
= t
->get_comp_byIndex(i
)->get_type();
5362 bool subresult
= false;
5363 if (memory
.has_key(t2
)) {
5364 switch (*memory
.get(t2
)) {
5366 // This type contains itself and is in the process
5367 // of being checked. Pretend it doesn't exist.
5368 // The answer will be determined by the other fields,
5369 // and it will propagate back up.
5370 // Avoids infinite recursion for self-referencing types.
5381 memory
.remember(t2
, PROCESSING
);
5382 subresult
= t2
->has_encoding(CT_XER
);
5385 if (subresult
) memory
.remember(t2
, ANSWER_YES
);
5386 else return memory
.remember(t2
, ANSWER_NO
);
5387 // Note: return only if the answer (false) is known.
5388 // If the answer is true, keep checking.
5390 // Empty record, or all fields supported XER: answer maybe yes.
5395 bool subresult
= false;
5396 Type
*t2
= t
->u
.seof
.ofType
;
5397 if (memory
.has_key(t2
)) {
5398 switch (*memory
.get(t2
)) {
5400 // Recursive record-of. This is OK because the recursion
5401 // can always be broken with an empty record-of.
5413 memory
.remember(t2
, PROCESSING
);
5414 // Check the contained type
5415 subresult
= t2
->has_encoding(CT_XER
);
5417 if (subresult
) break; // continue checking
5418 else return memory
.remember(t
, ANSWER_NO
); // No means no.
5421 case T_NULL
: // ASN.1 null
5422 case T_INT_A
: // ASN.1 integer
5423 case T_ENUM_A
:// ASN.1 enum
5424 case T_BSTR_A
:// ASN.1 bitstring
5425 case T_UTF8STRING
: // ASN.1
5426 case T_NUMERICSTRING
:
5427 case T_PRINTABLESTRING
:
5428 case T_TELETEXSTRING
:
5429 case T_VIDEOTEXSTRING
:
5431 case T_GRAPHICSTRING
:
5432 case T_VISIBLESTRING
:
5433 case T_GENERALSTRING
:
5434 case T_UNIVERSALSTRING
:
5436 case T_UNRESTRICTEDSTRING
: // still ASN.1
5437 case T_UTCTIME
: // ASN.1 string
5438 case T_GENERALIZEDTIME
: // ASN.1 string
5439 case T_OBJECTDESCRIPTOR
: // ASN.1 string
5440 case T_ROID
: // relative OID (ASN.1)
5443 case T_SEQ_A
: // ASN.1 versions of choice,sequence,set
5446 case T_OCFT
: // ObjectClassFieldType (ASN.1)
5447 case T_OPENTYPE
: // ASN.1 open type
5448 case T_ANY
: // deprecated ASN.1 ANY
5450 case T_EXTERNAL
: // ASN.1 external
5451 case T_EMBEDDED_PDV
: // ASN.1 embedded pdv
5452 case T_SELTYPE
: // selection type (ASN.1)
5453 FATAL_ERROR("Type::has_encoding(): typetype %d should be asn1",
5455 break; // not reached
5457 case T_REFD
: // reference to another type
5458 case T_ADDRESS
: // TTCN-3 address type
5459 case T_ARRAY
: // TTCN-3 array
5460 default: // FIXME: if compiling with -Wswitch, the default should be removed
5461 return memory
.remember(t
, ANSWER_NO
);
5462 } // switch t->typetype
5464 // Check to see if it has an encode "XML"; first the type itself,
5465 // then the root type.
5466 WithAttribPath
*aps
[2] = {0,0};
5467 size_t num_aps
= ((aps
[0] = this->get_attrib_path()) != 0);
5468 // assign, compare, then add 0 or 1
5470 num_aps
+= ((aps
[num_aps
] = t
->get_attrib_path()) != 0);
5472 for (size_t a
= 0; a
< num_aps
; ++a
) {
5473 const vector
<SingleWithAttrib
>& real
= aps
[a
]->get_real_attrib();
5474 const size_t num_atr
= real
.size();
5475 for (size_t i
= 0; i
< num_atr
; ++i
) {
5476 const SingleWithAttrib
& s
= *real
[i
];
5477 if (s
.get_attribKeyword() == SingleWithAttrib::AT_ENCODE
) {
5478 const string
& spec
= s
.get_attribSpec().get_spec();
5479 if (spec
== ex_emm_ell
// the right answer
5480 ||spec
== ex_ee_arr
) // the acceptable answer
5481 return memory
.remember(t
, ANSWER_YES
);
5482 else // if it has an encode other than XER, quit now
5483 return memory
.remember(t
, ANSWER_NO
);
5487 return memory
.remember(t
, ANSWER_NO
); // no encode XER
5490 return memory
.remember(t
, ANSWER_NO
); }
5494 if (t
->rawattrib
) return true;
5495 else if (t
->is_ref()) t
= t
->get_type_refd();
5497 switch (t
->typetype
) {
5506 // these basic types support RAW encoding by default
5516 if (t
->textattrib
) return true;
5517 else if (t
->is_ref()) t
= t
->get_type_refd();
5519 switch (t
->typetype
) {
5525 // these basic types support TEXT encoding by default
5535 if (json_mem
.has_key(t
)) {
5536 switch (*json_mem
.get(t
)) {
5545 if (t
->jsonattrib
) {
5546 return json_mem
.remember(t
, ANSWER_YES
);
5549 t
= t
->get_type_refd();
5552 switch (t
->typetype
) {
5565 case T_NUMERICSTRING
:
5566 case T_PRINTABLESTRING
:
5567 case T_TELETEXSTRING
:
5568 case T_VIDEOTEXSTRING
:
5570 case T_GRAPHICSTRING
:
5571 case T_VISIBLESTRING
:
5572 case T_GENERALSTRING
:
5573 case T_UNIVERSALSTRING
:
5576 // these basic types support JSON encoding by default
5577 return json_mem
.remember(t
, ANSWER_YES
);
5585 // all fields must also support JSON encoding
5586 size_t ncomp
= t
->get_nof_comps();
5587 for (size_t i
= 0; i
< ncomp
; ++i
) {
5588 Type
*t2
= t
->get_comp_byIndex(i
)->get_type();
5589 if (json_mem
.has_key(t2
)) {
5590 switch (*json_mem
.get(t2
)) {
5592 // This field is OK, but we still need to check the others
5594 // This type contains itself and is in the process
5595 // of being checked. Pretend it doesn't exist.
5596 // The answer will be determined by the other fields,
5597 // and it will propagate back up.
5598 // Avoids infinite recursion for self-referencing types.
5601 // One field is not OK => the structure is not OK
5602 return json_mem
.remember(t
, ANSWER_NO
);
5606 json_mem
.remember(t2
, PROCESSING
);
5607 bool enabled
= t2
->has_encoding(CT_JSON
);
5608 json_mem
.remember(t2
, enabled
? ANSWER_YES
: ANSWER_NO
);
5610 // One field is not OK => the structure is not OK
5611 return json_mem
.remember(t
, ANSWER_NO
);
5615 break; // check for an encode attribute
5620 Type
*t2
= t
->u
.seof
.ofType
;
5621 if (json_mem
.has_key(t2
)) {
5622 switch (*json_mem
.get(t2
)) {
5624 // Continue checking
5626 // Recursive record-of. This is OK because the recursion
5627 // can always be broken with an empty record-of.
5630 return json_mem
.remember(t
, ANSWER_NO
);
5635 json_mem
.remember(t2
, PROCESSING
);
5636 bool enabled
= t2
->has_encoding(CT_JSON
);
5637 json_mem
.remember(t2
, enabled
? ANSWER_YES
: ANSWER_NO
);
5639 // One field is not OK => the structure is not OK
5640 return json_mem
.remember(t
, ANSWER_NO
);
5643 break; // check for an encode attribute
5647 break; // check for an encode attribute
5649 return json_mem
.remember(t
, ANSWER_NO
);
5651 return json_mem
.remember(t
, hasEncodeAttr(CT_JSON
) ? ANSWER_YES
: ANSWER_NO
);
5656 FATAL_ERROR("Type::has_encoding()");
5662 bool Type::is_pure_refd()
5666 // ASN.1 parameterized references are not pure :)
5667 if(dynamic_cast<Asn::Ref_pard
*>(u
.ref
.ref
)) return false;
5672 if (sub_type
|| constraints
) return false;
5673 else if (tags
&& enable_ber()) return false;
5674 else if (rawattrib
&& enable_raw()) return false;
5675 else if (textattrib
&& enable_text()) return false;
5676 else if (enable_xer()) return false;
5677 else if (jsonattrib
&& enable_json()) return false;
5684 string
Type::create_stringRepr()
5686 if(is_tagged() || hasRawAttrs())
5687 return get_genname_own();
5690 return string("NULL");
5692 return string("BOOLEAN");
5695 return string("INTEGER");
5697 return string("REAL");
5700 return string("BIT__STRING");
5702 return string("HEX__STRING");
5704 return string("OCTET__STRING");
5706 return string("CHAR__STRING");
5708 return string("UNIVERSAL__CHARSTRING");
5710 return string("UTF8String");
5711 case T_NUMERICSTRING
:
5712 return string("NumericString");
5713 case T_PRINTABLESTRING
:
5714 return string("PrintableString");
5715 case T_TELETEXSTRING
:
5716 return string("TeletexString");
5717 case T_VIDEOTEXSTRING
:
5718 return string("VideotexString");
5720 return string("IA5String");
5721 case T_GRAPHICSTRING
:
5722 return string("GraphicString");
5723 case T_VISIBLESTRING
:
5724 return string("VisibleString");
5725 case T_GENERALSTRING
:
5726 return string("GeneralString");
5727 case T_UNIVERSALSTRING
:
5728 return string("UniversalString");
5730 return string("BMPString");
5731 case T_UNRESTRICTEDSTRING
:
5732 return string("CHARACTER__STRING");
5734 return string("UTCTime");
5735 case T_GENERALIZEDTIME
:
5736 return string("GeneralizedTime");
5737 case T_OBJECTDESCRIPTOR
:
5738 return string("ObjectDescriptor");
5740 return string("OBJECT__IDENTIFIER");
5742 return string("RELATIVE__OID");
5744 return string("ANY");
5749 if (tags
|| constraints
||
5750 (w_attrib_path
&& w_attrib_path
->has_attribs()))
5751 return get_genname_own();
5752 else return get_type_refd()->get_stringRepr();
5754 return string("<Error_type>");
5756 return get_genname_own();
5760 Identifier
Type::get_otaltname(bool& is_strange
)
5763 if (is_tagged() || is_constrained() || hasRawAttrs()) {
5764 s
= get_genname_own();
5766 } else if (typetype
== T_REFD
) {
5767 Ref_simple
* t_ref
=dynamic_cast<Ref_simple
*>(u
.ref
.ref
);
5769 const Identifier
*id
= t_ref
->get_id();
5770 const string
& dispname
= id
->get_dispname();
5771 if (dispname
.find('.') < dispname
.size()) {
5772 // id is not regular because t_ref is a parameterized reference
5773 // use that id anyway
5774 s
+= id
->get_name();
5777 Scope
*ass_scope
= t_ref
->get_refd_assignment()->get_my_scope();
5778 if (ass_scope
->get_parent_scope() == ass_scope
->get_scope_mod()) {
5779 // t_ref points to an assignment at module scope
5780 // use the simple id of the reference (in lowercase)
5784 // t_ref is a dummy reference in a parameterized assignment
5785 // (i.e. it points to a parameter assignment of an instantiation)
5786 // perform the same examination recursively on the referenced type
5787 // (which is the actual parameter)
5788 return get_type_refd()->get_otaltname(is_strange
);
5792 // the type comes from an information object [class]
5793 // examine the referenced type recursively
5794 return get_type_refd()->get_otaltname(is_strange
);
5797 s
= get_stringRepr();
5798 // throw away the leading @ if this is an instantiated type
5799 // (e.g. an in-line SEQUENCE from a parameterized reference)
5800 if (!strncmp(s
.c_str(), "_root_", 6)) s
.replace(0, 6, "");
5801 // the name is strange if it contains a single underscore
5803 // transform "__" -> "-"
5804 for (size_t pos
= 0; ; ) {
5805 pos
= s2
.find("__", pos
);
5806 if (pos
< s2
.size()) {
5807 s2
.replace(pos
, 2, "-");
5811 is_strange
= s2
.find('_') < s2
.size();
5814 size_t pos=s.find_if(0, s.size(), isupper);
5815 if(pos==s.size()) FATAL_ERROR("Type::get_otaltname() (`%s')", s.c_str());
5816 s[pos]=tolower(s[pos]);
5819 Identifier
tmp_id(Identifier::ID_NAME
, s
, true);
5820 /* This is because the origin of the returned ID must be ASN. */
5821 return Identifier(Identifier::ID_ASN
, tmp_id
.get_asnname());
5824 string
Type::get_genname_value(Scope
*p_scope
)
5826 Type
*t
= get_type_refd_last();
5827 switch (t
->typetype
) {
5830 case T_UNRESTRICTEDSTRING
:
5833 case T_EMBEDDED_PDV
:
5837 FATAL_ERROR("Type::get_genname_value()");
5839 return string("ASN_NULL");
5841 return string("BOOLEAN");
5844 return string("INTEGER");
5846 return string("FLOAT");
5849 return string("BITSTRING");
5851 return string("HEXSTRING");
5853 return string("OCTETSTRING");
5855 case T_NUMERICSTRING
:
5856 case T_PRINTABLESTRING
:
5858 case T_VISIBLESTRING
:
5860 case T_GENERALIZEDTIME
:
5861 return string("CHARSTRING");
5862 case T_USTR
: // ttcn3 universal charstring
5864 case T_TELETEXSTRING
:
5865 case T_VIDEOTEXSTRING
:
5866 case T_GRAPHICSTRING
:
5867 case T_GENERALSTRING
:
5868 case T_UNIVERSALSTRING
:
5870 case T_OBJECTDESCRIPTOR
:
5871 return string("UNIVERSAL_CHARSTRING");
5874 return string("OBJID");
5876 return string("ASN_ANY");
5878 return string("VERDICTTYPE");
5880 return string("COMPONENT");
5882 return string("DEFAULT");
5884 if (!t
->u
.array
.in_typedef
)
5885 return t
->u
.array
.dimension
->get_value_type(t
->u
.array
.element_type
,
5889 return t
->get_genname_own(p_scope
);
5893 string
Type::get_genname_template(Scope
*p_scope
)
5895 Type
*t
= get_type_refd_last();
5897 switch (t
->typetype
) {
5900 // template classes do not exist for these types
5901 FATAL_ERROR("Type::get_genname_template()");
5903 // a template class has to be instantiated in case of arrays
5904 // outside type definitions
5905 if (!t
->u
.array
.in_typedef
) {
5906 ret_val
= t
->u
.array
.dimension
->get_template_type(
5907 t
->u
.array
.element_type
, p_scope
);
5912 // in case of other types the name of the template class is derived
5913 // from the value class by appending a suffix
5914 ret_val
= t
->get_genname_value(p_scope
);
5915 ret_val
+= "_template";
5921 string
Type::get_genname_altname()
5923 Type
*t_last
= get_type_refd_last();
5924 Scope
*t_scope
= t_last
->get_my_scope();
5925 switch (t_last
->typetype
) {
5928 case T_UNRESTRICTEDSTRING
:
5931 case T_EMBEDDED_PDV
:
5935 FATAL_ERROR("Type::get_genname_altname()");
5947 case T_ANYTYPE
: // FIXME this does not yet work
5955 // user-defined types
5956 // always use the qualified name (including module identifier)
5957 string
ret_val(t_scope
->get_scope_mod_gen()->get_modid().get_name());
5959 ret_val
+= t_last
->get_genname_own();
5963 // use the simple class name from the base library
5964 return t_last
->get_genname_value(t_scope
);
5968 string
Type::get_typename()
5970 Type
*t
= get_type_refd_last();
5971 const char* tn
= get_typename_builtin(t
->typetype
);
5972 if (tn
!= 0) return string(tn
);
5973 switch (t
->typetype
) {
5991 return t
->get_fullname();
5993 string
dimensions(t
->u
.array
.dimension
->get_stringRepr());
5994 t
= t
->u
.array
.element_type
;
5995 while (t
->typetype
== T_ARRAY
) {
5996 dimensions
+= t
->u
.array
.dimension
->get_stringRepr();
5997 t
= t
->u
.array
.element_type
;
5999 return t
->get_typename() + dimensions
; }
6001 FATAL_ERROR("Type::get_typename()");
6007 const char* Type::get_typename_builtin(typetype_t tt
)
6011 return "Erroneous type";
6027 return "octetstring";
6029 return "charstring";
6031 return "universal charstring";
6033 return "UTF8String";
6034 case T_NUMERICSTRING
:
6035 return "NumericString";
6036 case T_PRINTABLESTRING
:
6037 return "PrintableString";
6038 case T_TELETEXSTRING
:
6039 return "TeletexString";
6040 case T_VIDEOTEXSTRING
:
6041 return "VideotexString";
6044 case T_GRAPHICSTRING
:
6045 return "GraphicString";
6046 case T_VISIBLESTRING
:
6047 return "VisibleString";
6048 case T_GENERALSTRING
:
6049 return "GeneralString";
6050 case T_UNIVERSALSTRING
:
6051 return "UniversalString";
6056 case T_GENERALIZEDTIME
:
6057 return "GeneralizedTime";
6058 case T_OBJECTDESCRIPTOR
:
6059 return "ObjectDescriptor";
6066 return "verdicttype";
6071 case T_EMBEDDED_PDV
:
6072 return "EMBEDDED PDV";
6073 case T_UNRESTRICTEDSTRING
:
6074 return "CHARACTER STRING";
6084 string
Type::get_genname_typedescriptor(Scope
*p_scope
)
6088 /* If it has tags or encoding attributes, then its encoding may be
6089 * different from the other "equivalent" types and needs to have its own
6092 if (t
->is_tagged() || t
->rawattrib
|| t
->textattrib
|| t
->jsonattrib
||
6093 (t
->xerattrib
&& !t
->xerattrib
->empty() ))
6095 return t
->get_genname_own(p_scope
);
6097 else if (t
->is_ref()) {
6098 if (t
->has_encoding(CT_XER
)) {
6099 // just fetch the referenced type and return
6100 return t
->get_type_refd()->get_genname_own(p_scope
);
6103 { // follow the white rabbit
6104 t
= t
->get_type_refd();
6109 return t
->get_genname_typename(p_scope
);
6112 string
Type::get_genname_typename(Scope
*p_scope
)
6114 Type
*t
= get_type_refd_last();
6115 switch (t
->typetype
) {
6117 return string("UTF8String");
6118 case T_NUMERICSTRING
:
6119 return string("NumericString");
6120 case T_PRINTABLESTRING
:
6121 return string("PrintableString");
6122 case T_TELETEXSTRING
:
6123 return string("TeletexString");
6124 case T_VIDEOTEXSTRING
:
6125 return string("VideotexString");
6127 return string("IA5String");
6128 case T_GRAPHICSTRING
:
6129 return string("GraphicString");
6130 case T_VISIBLESTRING
:
6131 return string("VisibleString");
6132 case T_GENERALSTRING
:
6133 return string("GeneralString");
6134 case T_UNIVERSALSTRING
:
6135 return string("UniversalString");
6137 return string("BMPString");
6139 return string("ASN_UTCTime");
6140 case T_GENERALIZEDTIME
:
6141 return string("ASN_GeneralizedTime");
6142 case T_OBJECTDESCRIPTOR
:
6143 return string("ObjectDescriptor");
6145 return string("ASN_ROID");
6147 return t
->get_genname_value(p_scope
);
6151 string
Type::get_genname_berdescriptor()
6155 if (t
->is_tagged()) return t
->get_genname_own(my_scope
);
6156 else if (t
->is_ref()) t
= t
->get_type_refd();
6159 switch (t
->typetype
) {
6162 return string("ENUMERATED");
6166 return string("CHOICE");
6170 return string("SEQUENCE");
6174 return string("SET");
6176 return t
->get_genname_typename(my_scope
);
6180 string
Type::get_genname_rawdescriptor()
6184 if (t
->rawattrib
) return t
->get_genname_own(my_scope
);
6185 else if (t
->is_ref()) t
= t
->get_type_refd();
6188 return t
->get_genname_typename(my_scope
);
6191 string
Type::get_genname_textdescriptor()
6195 if (t
->textattrib
) return t
->get_genname_own(my_scope
);
6196 else if (t
->is_ref()) t
= t
->get_type_refd();
6199 return t
->get_genname_typename(my_scope
);
6202 string
Type::get_genname_xerdescriptor()
6204 if (T_REFDSPEC
== typetype
) {
6205 return get_genname_typedescriptor(my_scope
);
6207 else return genname
;
6210 string
Type::get_genname_jsondescriptor()
6214 if (t
->jsonattrib
) return t
->get_genname_own(my_scope
);
6215 else if (t
->is_ref()) t
= t
->get_type_refd();
6218 return t
->get_genname_typename(my_scope
);
6221 const char* Type::get_genname_typedescr_asnbasetype()
6223 switch (get_type_refd_last()->typetype
) {
6226 case T_UNIVERSALSTRING
:
6227 return "UNIVERSALSTRING";
6229 return "UTF8STRING";
6230 case T_TELETEXSTRING
:
6231 return "TELETEXSTRING";
6232 case T_VIDEOTEXSTRING
:
6233 return "VIDEOTEXSTRING";
6234 case T_OBJECTDESCRIPTOR
:
6235 case T_GRAPHICSTRING
:
6236 return "GRAPHICSTRING";
6237 case T_GENERALSTRING
:
6238 return "GENERALSTRING";
6248 void Type::dump(unsigned level
) const
6250 DEBUG(level
, "Type @ %p, '%s'", (const void*)this, get_fullname().c_str());
6253 DEBUG(level
, "Type: <erroneous>");
6256 DEBUG(level
, "Type: NULL");
6259 DEBUG(level
, "Type: boolean");
6262 DEBUG(level
, "Type: integer");
6265 DEBUG(level
, "Type: INTEGER");
6266 if(u
.namednums
.block
)
6267 DEBUG(level
, "with unparsed block");
6268 if(u
.namednums
.nvs
) {
6269 DEBUG(level
, "with named numbers (%lu pcs.)",
6270 (unsigned long) u
.namednums
.nvs
->get_nof_nvs());
6271 u
.namednums
.nvs
->dump(level
+1);
6275 DEBUG(level
, "Type: float/REAL");
6279 DEBUG(level
, "Type: enumerated");
6280 u
.enums
.eis
->dump(level
+1);
6283 DEBUG(level
, "Type: bitstring");
6286 DEBUG(level
, "Type: BIT STRING");
6287 if(u
.namednums
.block
)
6288 DEBUG(level
, "with unparsed block");
6289 if(u
.namednums
.nvs
) {
6290 DEBUG(level
, "with named numbers (%lu pcs.)",
6291 (unsigned long) u
.namednums
.nvs
->get_nof_nvs());
6292 u
.namednums
.nvs
->dump(level
+1);
6296 DEBUG(level
, "Type: hexstring");
6299 DEBUG(level
, "Type: octetstring");
6302 DEBUG(level
, "Type: charstring");
6305 DEBUG(level
, "Type: universal charstring");
6308 DEBUG(level
, "Type: UTF8String");
6310 case T_NUMERICSTRING
:
6311 DEBUG(level
, "Type: NumericString");
6313 case T_PRINTABLESTRING
:
6314 DEBUG(level
, "Type: PrintableString");
6316 case T_TELETEXSTRING
:
6317 DEBUG(level
, "Type: TeletexString");
6319 case T_VIDEOTEXSTRING
:
6320 DEBUG(level
, "Type: VideotexString");
6323 DEBUG(level
, "Type: IA5String");
6325 case T_GRAPHICSTRING
:
6326 DEBUG(level
, "Type: GraphicString");
6328 case T_VISIBLESTRING
:
6329 DEBUG(level
, "Type: VisibleString");
6331 case T_GENERALSTRING
:
6332 DEBUG(level
, "Type: GeneralString");
6334 case T_UNIVERSALSTRING
:
6335 DEBUG(level
, "Type: UniversalString");
6338 DEBUG(level
, "Type: BMPString");
6340 case T_UNRESTRICTEDSTRING
:
6341 DEBUG(level
, "Type: CHARACTER STRING");
6344 DEBUG(level
, "Type: UTCTime");
6346 case T_GENERALIZEDTIME
:
6347 DEBUG(level
, "Type: GeneralizedTime");
6349 case T_OBJECTDESCRIPTOR
:
6350 DEBUG(level
, "Type: OBJECT DESCRIPTOR");
6353 DEBUG(level
, "Type: objid/OBJECT IDENTIFIER");
6356 DEBUG(level
, "Type: RELATIVE-OID");
6359 DEBUG(level
, "Type: anytype!!!");
6360 u
.secho
.cfm
->dump(level
+1);
6363 DEBUG(level
, "Type: union");
6364 u
.secho
.cfm
->dump(level
+1);
6367 DEBUG(level
, "Type: CHOICE");
6369 DEBUG(level
, "with unparsed block");
6371 DEBUG(level
, "with alternatives (%lu pcs.)",
6372 (unsigned long) u
.secho
.ctss
->get_nof_comps());
6373 u
.secho
.ctss
->dump(level
+1);
6377 DEBUG(level
, "Type: record of/SEQUENCE OF");
6378 DEBUG(level
+1, "of type:");
6379 u
.seof
.ofType
->dump(level
+2);
6382 DEBUG(level
, "Type: set of/SET OF");
6383 DEBUG(level
+1, "of type:");
6384 u
.seof
.ofType
->dump(level
+2);
6387 DEBUG(level
, "Type: record");
6388 u
.secho
.cfm
->dump(level
+1);
6391 DEBUG(level
, "Type: set");
6392 u
.secho
.cfm
->dump(level
+1);
6395 DEBUG(level
, "Type: SEQUENCE");
6397 DEBUG(level
, "with unparsed block");
6399 DEBUG(level
, "with components (%lu pcs.)",
6400 (unsigned long) u
.secho
.ctss
->get_nof_comps());
6401 u
.secho
.ctss
->dump(level
+1);
6405 DEBUG(level
, "Type: SET");
6407 DEBUG(level
, "with unparsed block");
6409 DEBUG(level
, "with components (%lu pcs.)",
6410 (unsigned long) u
.secho
.ctss
->get_nof_comps());
6411 u
.secho
.ctss
->dump(level
+1);
6415 DEBUG(level
, "Type: ObjectClassFieldType (%s)",
6416 const_cast<Type
*>(this)->get_type_refd()->get_stringRepr().c_str());
6419 DEBUG(level
, "Type: opentype (mapped to CHOICE)");
6420 u
.secho
.cfm
->dump(level
+1);
6423 DEBUG(level
, "Type: ANY");
6426 DEBUG(level
, "Type: EXTERNAL");
6428 case T_EMBEDDED_PDV
:
6429 DEBUG(level
, "Type: EMBEDDED PDV");
6432 DEBUG(level
, "Type: reference");
6433 u
.ref
.ref
->dump(level
+1);
6434 if(u
.ref
.type_refd
&& u
.ref
.type_refd
->typetype
==T_OPENTYPE
)
6435 u
.ref
.type_refd
->dump(level
+1);
6438 DEBUG(level
, "Type: reference (spec) to %s:",
6439 u
.ref
.type_refd
->get_fullname().c_str());
6440 u
.ref
.type_refd
->dump(level
+ 1);
6443 DEBUG(level
, "Type: selection type");
6444 DEBUG(level
+1, "`%s' <", u
.seltype
.id
->get_dispname().c_str());
6445 u
.seltype
.type
->dump(level
+1);
6448 DEBUG(level
, "Type: verdicttype");
6451 DEBUG(level
, "Type: port");
6452 u
.port
->dump(level
+ 1);
6455 DEBUG(level
, "Type: component");
6456 u
.component
->dump(level
+ 1);
6459 DEBUG(level
, "Type: address");
6462 DEBUG(level
, "Type: default");
6465 DEBUG(level
, "Type: array");
6466 DEBUG(level
+ 1, "element type:");
6467 u
.array
.element_type
->dump(level
+ 2);
6468 DEBUG(level
+ 1, "dimension:");
6469 u
.array
.dimension
->dump(level
+ 2);
6472 DEBUG(level
, "Type: signature");
6473 if (u
.signature
.parameters
) {
6474 DEBUG(level
+1,"parameter(s):");
6475 u
.signature
.parameters
->dump(level
+2);
6477 if (u
.signature
.return_type
) {
6478 DEBUG(level
+1,"return type");
6479 u
.signature
.return_type
->dump(level
+2);
6481 if (u
.signature
.no_block
) DEBUG(level
+1,"no block");
6482 if (u
.signature
.exceptions
) {
6483 DEBUG(level
+1,"exception(s):");
6484 u
.signature
.exceptions
->dump(level
+2);
6488 DEBUG(level
, "Type: function");
6489 DEBUG(level
+1, "Parameters:");
6490 u
.fatref
.fp_list
->dump(level
+2);
6491 if (u
.fatref
.return_type
) {
6492 if (!u
.fatref
.returns_template
) {
6493 DEBUG(level
+1, "Return type:");
6495 if (u
.fatref
.template_restriction
==TR_OMIT
)
6496 DEBUG(level
+1, "Returns template of type:");
6498 DEBUG(level
+1, "Returns template(%s) of type:",
6499 Template::get_restriction_name(u
.fatref
.template_restriction
));
6501 u
.fatref
.return_type
->dump(level
+2);
6503 if(u
.fatref
.runs_on
.ref
) {
6504 DEBUG(level
+1, "Runs on clause:");
6505 u
.fatref
.runs_on
.ref
->dump(level
+2);
6507 if (u
.fatref
.runs_on
.self
) DEBUG(level
+1, "Runs on self");
6511 DEBUG(level
, "Type: altstep");
6512 DEBUG(level
+1, "Parameters:");
6513 u
.fatref
.fp_list
->dump(level
+2);
6514 if(u
.fatref
.runs_on
.ref
) {
6515 DEBUG(level
+1, "Runs on clause:");
6516 u
.fatref
.runs_on
.ref
->dump(level
+2);
6518 if (u
.fatref
.runs_on
.self
) DEBUG(level
+1, "Runs on self");
6522 DEBUG(level
, "Type: testcase");
6523 DEBUG(level
+1, "Parameters:");
6524 u
.fatref
.fp_list
->dump(level
+2);
6525 if(u
.fatref
.runs_on
.ref
) {
6526 DEBUG(level
+1, "Runs on clause:");
6527 u
.fatref
.runs_on
.ref
->dump(level
+2);
6529 if(u
.fatref
.system
.ref
) {
6530 DEBUG(level
+1, "System clause:");
6531 u
.fatref
.system
.ref
->dump(level
+2);
6535 DEBUG(level
, "type (%d - %s)", typetype
, const_cast<Type
*>(this)->get_stringRepr().c_str());
6537 DEBUG(level
, "ownertype %2d", ownertype
);
6538 if(sub_type
!=NULL
) {
6539 DEBUG(level
, "with subtype");
6540 sub_type
->dump(level
+1);
6543 DEBUG(level
, "with tags");
6544 tags
->dump(level
+1);
6547 if(w_attrib_path
&& w_attrib_path
->get_with_attr())
6549 DEBUG(level
, "Attributes");
6550 w_attrib_path
->dump(level
);
6551 //w_attrib_path->get_with_attr()->dump(level);
6555 xerattrib
->print(get_fullname().c_str());
6559 SubtypeConstraint::subtype_t
Type::get_subtype_type()
6561 Type
* t
= get_type_refd_last();
6562 switch (t
->get_typetype()) {
6565 return SubtypeConstraint::ST_INTEGER
;
6567 return SubtypeConstraint::ST_FLOAT
;
6569 return SubtypeConstraint::ST_BOOLEAN
;
6571 return SubtypeConstraint::ST_VERDICTTYPE
;
6574 return SubtypeConstraint::ST_OBJID
;
6577 return SubtypeConstraint::ST_BITSTRING
;
6579 return SubtypeConstraint::ST_HEXSTRING
;
6581 return SubtypeConstraint::ST_OCTETSTRING
;
6582 case T_TELETEXSTRING
:
6583 case T_VIDEOTEXSTRING
:
6584 case T_GRAPHICSTRING
:
6585 case T_GENERALSTRING
:
6586 case T_OBJECTDESCRIPTOR
:
6589 case T_NUMERICSTRING
:
6590 case T_PRINTABLESTRING
:
6592 case T_VISIBLESTRING
:
6594 case T_GENERALIZEDTIME
:
6595 return SubtypeConstraint::ST_CHARSTRING
;
6598 case T_UNIVERSALSTRING
:
6600 return SubtypeConstraint::ST_UNIVERSAL_CHARSTRING
;
6603 case T_NULL
: // FIXME: this should have it's own ST_NULL case
6604 return SubtypeConstraint::ST_ENUM
;
6607 case T_ANYTYPE
: // (titan's hacked anytype is a choice)
6609 return SubtypeConstraint::ST_UNION
;
6611 return SubtypeConstraint::ST_RECORDOF
;
6613 return SubtypeConstraint::ST_SETOF
;
6616 case T_EXTERNAL
: // associated ASN.1 type is a SEQUENCE
6617 case T_EMBEDDED_PDV
: // associated ASN.1 type is a SEQUENCE
6618 case T_UNRESTRICTEDSTRING
: // associated ASN.1 type is a SEQUENCE
6619 return SubtypeConstraint::ST_RECORD
;
6622 return SubtypeConstraint::ST_SET
;
6624 return SubtypeConstraint::ST_FUNCTION
;
6626 return SubtypeConstraint::ST_ALTSTEP
;
6628 return SubtypeConstraint::ST_TESTCASE
;
6630 return SubtypeConstraint::ST_ERROR
;
6634 void Type::set_parsed_restrictions(vector
<SubTypeParse
> *stp
)
6636 if(!parsed_restr
)parsed_restr
=stp
;
6637 else FATAL_ERROR("Type::set_parsed_restrictions(): restrictions "
6638 "are already set.");
6641 bool Type::is_component_internal()
6643 if (!checked
) chk();
6650 return u
.fatref
.runs_on
.self
;
6654 return u
.secho
.component_internal
;
6657 return u
.seof
.component_internal
;
6659 return u
.array
.component_internal
;
6661 return u
.signature
.component_internal
;
6664 return u
.ref
.component_internal
;
6670 void Type::chk_component_internal(map
<Type
*,void>& type_chain
,
6673 Type
* t_last
= get_type_refd_last();
6674 switch (t_last
->typetype
) {
6675 // types that cannot be sent
6677 error("Default type cannot be %s", p_what
);
6680 error("Port type `%s' cannot be %s", t_last
->get_typename().c_str(),
6684 if (t_last
->u
.fatref
.runs_on
.self
) {
6685 error("Function type `%s' with 'runs on self' clause cannot be %s",
6686 t_last
->get_typename().c_str(), p_what
);
6690 if (t_last
->u
.fatref
.runs_on
.self
) {
6691 error("Altstep type `%s' with 'runs on self' clause cannot be %s",
6692 t_last
->get_typename().c_str(), p_what
);
6695 // structured types that may contain types that cannot be sent
6703 if (type_chain
.has_key(t_last
)) break;
6704 type_chain
.add(t_last
, 0);
6705 Error_Context
cntxt(this, "In type `%s'", get_typename().c_str());
6706 switch (t_last
->typetype
) {
6710 size_t nof_comps
= t_last
->get_nof_comps();
6711 for (size_t i
=0; i
<nof_comps
; i
++) {
6712 Type
* t
= t_last
->get_comp_byIndex(i
)->get_type();
6713 if (t
->is_component_internal())
6714 t
->chk_component_internal(type_chain
, p_what
);
6719 if (t_last
->u
.seof
.ofType
->is_component_internal())
6720 t_last
->u
.seof
.ofType
->chk_component_internal(type_chain
, p_what
);
6723 if (t_last
->u
.array
.element_type
->is_component_internal())
6724 t_last
->u
.array
.element_type
->chk_component_internal(type_chain
,
6728 if (t_last
->u
.signature
.parameters
) {
6729 size_t nof_params
= t_last
->u
.signature
.parameters
->get_nof_params();
6730 for (size_t i
=0; i
<nof_params
; i
++) {
6731 Type
* t
= t_last
->u
.signature
.parameters
->
6732 get_param_byIndex(i
)->get_type();
6733 if (t
->is_component_internal())
6734 t
->chk_component_internal(type_chain
, p_what
);
6737 if (t_last
->u
.signature
.return_type
&&
6738 t_last
->u
.signature
.return_type
->is_component_internal()) {
6739 t_last
->u
.signature
.return_type
->chk_component_internal(type_chain
,
6742 if (t_last
->u
.signature
.exceptions
) {
6743 size_t nof_types
= t_last
->u
.signature
.exceptions
->get_nof_types();
6744 for (size_t i
=0; i
<nof_types
; i
++) {
6745 Type
* t
= t_last
->u
.signature
.exceptions
->get_type_byIndex(i
);
6746 if (t
->is_component_internal())
6747 t
->chk_component_internal(type_chain
, p_what
);
6752 FATAL_ERROR("Type::chk_component_internal()");
6754 type_chain
.erase(t_last
);
6756 default: //all other types are Ok.
6761 Type::typetype_t
Type::search_for_not_allowed_type(map
<Type
*,void>& type_chain
,
6762 map
<typetype_t
, void>& not_allowed
)
6764 if (!checked
) chk();
6765 Type
* t_last
= get_type_refd_last();
6766 Type::typetype_t ret
= t_last
->typetype
;
6768 if (not_allowed
.has_key(t_last
->typetype
)) {
6772 switch (t_last
->typetype
) {
6779 if (type_chain
.has_key(t_last
)) {
6782 type_chain
.add(t_last
, 0);
6783 switch (t_last
->typetype
) {
6787 size_t nof_comps
= t_last
->get_nof_comps();
6788 for (size_t i
= 0; i
< nof_comps
; ++i
) {
6789 Type
* t
= t_last
->get_comp_byIndex(i
)->get_type();
6790 ret
= t
->search_for_not_allowed_type(type_chain
, not_allowed
);
6791 if (not_allowed
.has_key(ret
)) {
6799 ret
= t_last
->get_ofType()->search_for_not_allowed_type(type_chain
, not_allowed
);
6800 if (not_allowed
.has_key(ret
)) {
6807 type_chain
.erase(t_last
);
6813 return t_last
->typetype
;
6816 string
Type::get_dispname() const
6818 if (T_REFD
== typetype
) {
6819 // cannot calculate the display name for referenced types this way
6820 FATAL_ERROR("Type::get_dispname()");
6822 string dispname
= genname
;
6824 while(pos
< dispname
.size()) {
6825 pos
= dispname
.find("__", pos
);
6826 if (pos
== dispname
.size()) {
6829 dispname
.replace(pos
, 1, "");
6835 } // namespace Common