| 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 | #ifndef _Common_Type_HH |
| 9 | #define _Common_Type_HH |
| 10 | |
| 11 | #include "Setting.hh" |
| 12 | #include "Code.hh" |
| 13 | #include "Int.hh" |
| 14 | #include "subtype.hh" |
| 15 | #include "ttcn3/rawASTspec.h" |
| 16 | #include "ttcn3/RawAST.hh" |
| 17 | #include "ttcn3/TextAST.hh" |
| 18 | #include "ttcn3/BerAST.hh" |
| 19 | #include "ttcn3/JsonAST.hh" |
| 20 | #include <float.h> |
| 21 | |
| 22 | class XerAttributes; |
| 23 | enum namedbool { INCOMPLETE_NOT_ALLOWED = 0, INCOMPLETE_ALLOWED = 1, |
| 24 | NO_SUB_CHK = 0, SUB_CHK = 2, OMIT_NOT_ALLOWED = 0, OMIT_ALLOWED = 3, |
| 25 | ANY_OR_OMIT_NOT_ALLOWED = 0, ANY_OR_OMIT_ALLOWED = 4, |
| 26 | NOT_IMPLICIT_OMIT = 0, IMPLICIT_OMIT = 5, NOT_STR_ELEM = 0, IS_STR_ELEM = 6 |
| 27 | }; |
| 28 | |
| 29 | namespace Asn { |
| 30 | // not defined here |
| 31 | class Tags; |
| 32 | class Tag; |
| 33 | class TagCollection; |
| 34 | class Block; |
| 35 | class OC_defn; |
| 36 | class TableConstraint; |
| 37 | } // namespace Asn |
| 38 | |
| 39 | namespace Ttcn { |
| 40 | // not defined here |
| 41 | class ArrayDimension; |
| 42 | class FieldOrArrayRefs; |
| 43 | class Template; |
| 44 | class Definitions; |
| 45 | class Definition; |
| 46 | class SingleWithAttrib; |
| 47 | class MultiWithAttrib; |
| 48 | class WithAttribPath; |
| 49 | class FormalPar; |
| 50 | class FormalParList; |
| 51 | class Reference; |
| 52 | class PortTypeBody; |
| 53 | class Def_Type; |
| 54 | class Ref_pard; |
| 55 | } // namespace Ttcn |
| 56 | |
| 57 | // not defined here |
| 58 | class JSON_Tokenizer; |
| 59 | |
| 60 | namespace Common { |
| 61 | |
| 62 | /** |
| 63 | * \ingroup AST |
| 64 | * |
| 65 | * \defgroup AST_Type Type |
| 66 | * @{ |
| 67 | */ |
| 68 | using Asn::Tag; |
| 69 | using Asn::Tags; |
| 70 | using Asn::TagCollection; |
| 71 | using Asn::Block; |
| 72 | using Asn::OC_defn; |
| 73 | using Asn::TableConstraint; |
| 74 | using Ttcn::Template; |
| 75 | |
| 76 | class Type; |
| 77 | |
| 78 | // not defined here |
| 79 | class Identifier; |
| 80 | class Constraints; |
| 81 | class Value; |
| 82 | class CompField; |
| 83 | class CompFieldMap; |
| 84 | class EnumItem; |
| 85 | class EnumItems; |
| 86 | class ExcSpec; |
| 87 | class NamedValues; |
| 88 | class CTs_EE_CTs; |
| 89 | class TypeSet; |
| 90 | class TypeChain; |
| 91 | class TypeCompatInfo; |
| 92 | class ComponentTypeBody; |
| 93 | class SignatureParam; |
| 94 | class SignatureParamList; |
| 95 | class SignatureExceptions; |
| 96 | class CodeGenHelper; |
| 97 | |
| 98 | /** |
| 99 | * This is the base class for types. |
| 100 | */ |
| 101 | class Type : public Governor { |
| 102 | public: |
| 103 | |
| 104 | /** type of type */ |
| 105 | enum typetype_t { |
| 106 | /** Undefined. |
| 107 | * There is never a Type object with this typetype. |
| 108 | * It may be returned by Value::get_expr_returntype() or |
| 109 | * ValueRange::get_expr_returntype(). */ |
| 110 | T_UNDEF, |
| 111 | T_ERROR, /**< erroneous (e.g. nonexistent reference) */ |
| 112 | T_NULL, /**< null (ASN.1) */ |
| 113 | T_BOOL, /**< boolean */ |
| 114 | T_INT, /**< integer */ |
| 115 | T_INT_A, /**< integer / ASN */ |
| 116 | T_REAL, /**< real/float */ |
| 117 | T_ENUM_A, /**< enumerated / ASN */ |
| 118 | T_ENUM_T, /**< enumerated / TTCN */ |
| 119 | T_BSTR, /**< bitstring */ |
| 120 | T_BSTR_A, /**< bitstring */ |
| 121 | T_HSTR, /**< hexstring (TTCN-3) */ |
| 122 | T_OSTR, /**< octetstring */ |
| 123 | T_CSTR, /**< charstring (TTCN-3) */ |
| 124 | T_USTR, /**< universal charstring (TTCN-3) */ |
| 125 | T_UTF8STRING, /**< UTF8String (ASN.1) */ |
| 126 | T_NUMERICSTRING, /**< NumericString (ASN.1) */ |
| 127 | T_PRINTABLESTRING, /**< PrintableString (ASN.1) */ |
| 128 | T_TELETEXSTRING, /**< TeletexString (ASN.1) */ |
| 129 | T_VIDEOTEXSTRING, /**< VideotexString (ASN.1) */ |
| 130 | T_IA5STRING, /**< IA5String (ASN.1) */ |
| 131 | T_GRAPHICSTRING, /**< GraphicString (ASN.1) */ |
| 132 | T_VISIBLESTRING, /**< VisibleString (ASN.1) */ |
| 133 | T_GENERALSTRING, /**< GeneralString (ASN.1) */ |
| 134 | T_UNIVERSALSTRING, /**< UniversalString (ASN.1) */ |
| 135 | T_BMPSTRING, /**< BMPString (ASN.1) */ |
| 136 | T_UNRESTRICTEDSTRING, /**< UnrestrictedCharacterString (ASN.1) */ |
| 137 | T_UTCTIME, /**< UTCTime (ASN.1) */ |
| 138 | T_GENERALIZEDTIME, /**< GeneralizedTime (ASN.1) */ |
| 139 | T_OBJECTDESCRIPTOR, /** Object descriptor, a kind of string (ASN.1) */ |
| 140 | T_OID, /**< object identifier */ |
| 141 | T_ROID, /**< relative OID (ASN.1) */ |
| 142 | T_CHOICE_A, /**< choice /ASN, uses u.secho */ |
| 143 | T_CHOICE_T, /**< union /TTCN, uses u.secho */ |
| 144 | T_SEQOF, /**< sequence (record) of */ |
| 145 | T_SETOF, /**< set of */ |
| 146 | T_SEQ_A, /**< sequence /ASN, uses u.secho */ |
| 147 | T_SEQ_T, /**< record /TTCN, uses u.secho */ |
| 148 | T_SET_A, /**< set /ASN, uses u.secho */ |
| 149 | T_SET_T, /**< set /TTCN, uses u.secho */ |
| 150 | T_OCFT, /**< ObjectClassFieldType (ASN.1) */ |
| 151 | T_OPENTYPE, /**< open type (ASN.1) */ |
| 152 | T_ANY, /**< ANY (deprecated ASN.1) */ |
| 153 | T_EXTERNAL, /**< %EXTERNAL (ASN.1) */ |
| 154 | T_EMBEDDED_PDV, /**< EMBEDDED PDV (ASN.1) */ |
| 155 | T_REFD, /**< referenced */ |
| 156 | T_REFDSPEC, /**< special referenced (by pointer, not by name) */ |
| 157 | T_SELTYPE, /**< selection type (ASN.1) */ |
| 158 | T_VERDICT, /**< verdict type (TTCN-3) */ |
| 159 | T_PORT, /**< port type (TTCN-3) */ |
| 160 | T_COMPONENT, /**< component type (TTCN-3) */ |
| 161 | T_ADDRESS, /**< address type (TTCN-3) */ |
| 162 | T_DEFAULT, /**< default type (TTCN-3) */ |
| 163 | T_ARRAY, /**< array (TTCN-3), uses u.array */ |
| 164 | T_SIGNATURE, /**< signature (TTCN-3) */ |
| 165 | T_FUNCTION, /**< function reference (TTCN-3) */ |
| 166 | T_ALTSTEP, /**< altstep reference (TTCN-3) */ |
| 167 | T_TESTCASE, /**< testcase reference (TTCN-3) */ |
| 168 | T_ANYTYPE, /**< anytype (TTCN-3) */ |
| 169 | // WRITE new type before this line |
| 170 | T_LAST |
| 171 | }; //DO NOT FORGET to update type_as_string[] in Type.cc |
| 172 | |
| 173 | /** |
| 174 | * Enumeration to represent message encoding types. |
| 175 | */ |
| 176 | enum MessageEncodingType_t { |
| 177 | CT_UNDEF, /**< undefined/unused */ |
| 178 | CT_BER, /**< ASN.1 BER */ |
| 179 | CT_PER, /**< ASN.1 PER (not supported yet) */ |
| 180 | CT_RAW, /**< TTCN-3 RAW */ |
| 181 | CT_TEXT, /**< TTCN-3 TEXT */ |
| 182 | CT_XER, /**< ASN.1 XER */ |
| 183 | CT_JSON /**< TTCN-3 JSON */ |
| 184 | }; |
| 185 | |
| 186 | /** selector for value checking algorithms */ |
| 187 | enum expected_value_t { |
| 188 | /** the value must be known at compile time (i.e. it may refer |
| 189 | * to a TTCN-3 constant or an ASN.1 value) */ |
| 190 | EXPECTED_CONSTANT, |
| 191 | /** the value must be static at execution time, but may be |
| 192 | * unknown at compilation time (i.e. it may refer to a TTCN-3 |
| 193 | * module parameter as well) */ |
| 194 | EXPECTED_STATIC_VALUE, |
| 195 | /** the value is known only at execution time (i.e. it may refer |
| 196 | * to a variable in addition to static values) */ |
| 197 | EXPECTED_DYNAMIC_VALUE, |
| 198 | /** the reference may point to a dynamic value or a template |
| 199 | * (this selector is also used in template bodies where the |
| 200 | * variable references are unaccessible because of the scope |
| 201 | * hierarchy) */ |
| 202 | EXPECTED_TEMPLATE |
| 203 | }; |
| 204 | |
| 205 | /** Enumeration to represent the owner of the type. |
| 206 | * Also align OT_UNKNOWN at line 200. */ |
| 207 | enum TypeOwner_t { |
| 208 | OT_UNKNOWN, |
| 209 | OT_TYPE_ASS, ///< ASN.1 type assignment (Ass_T) |
| 210 | OT_VAR_ASS, ///< ASN.1 variable assignment (Ass_V) |
| 211 | OT_VSET_ASS, ///< ASN.1 value set assignment (Ass_VS) |
| 212 | OT_TYPE_FLD, ///< ASN.1 TypeFieldSpec (FieldSpec_T) |
| 213 | OT_FT_V_FLD, ///< ASN.1 FixedTypeValueFieldSpec (FieldSpec_V_FT) |
| 214 | OT_TYPE_MAP, ///< TTCN-3 TypeMapping |
| 215 | OT_TYPE_MAP_TARGET, ///< TTCN-3 TypeMappingTarget |
| 216 | OT_TYPE_DEF, ///< TTCN-3 type definition (Def_Type) |
| 217 | OT_CONST_DEF, ///< TTCN-3 constant definition (DefConst, Def_ExtCOnst) |
| 218 | OT_MODPAR_DEF, ///< TTCN-3 module parameter definition (Def_Modulepar) |
| 219 | OT_VAR_DEF, ///< TTCN-3 variable definition (Def_Var) |
| 220 | OT_VARTMPL_DEF, ///< TTCN-3 var template definition (Def_Var_Template) |
| 221 | OT_FUNCTION_DEF, ///< TTCN-3 function (Def_Function, Def_ExtFunction) |
| 222 | OT_TEMPLATE_DEF, ///< TTCN-3 template definition (Def_Template) |
| 223 | OT_ARRAY, ///< another Type: TTCN-3 array(T_ARRAY) |
| 224 | OT_RECORD_OF, ///< another Type (T_SEQOF, T_SETOF), ASN.1 or TTCN-3 |
| 225 | OT_FUNCTION, ///< another Type: TTCN-3 function (T_FUNCTION) |
| 226 | OT_SIGNATURE, ///< another Type: TTCN-3 signature (T_SIGNATURE) |
| 227 | OT_REF, ///< another Type (T_REFD) |
| 228 | OT_REF_SPEC, ///< another Type (T_REFDSPEC) |
| 229 | OT_COMP_FIELD, ///< a field of a record/set/union (CompField) |
| 230 | OT_COMPS_OF, ///< ASN.1 "COMPONENTS OF" (CT_CompsOf) |
| 231 | OT_FORMAL_PAR, ///< formal parameter (FormalPar), TTCN-3 |
| 232 | OT_TYPE_LIST, ///< TypeList for a 'with "extension anytype t1,t2..." ' |
| 233 | OT_FIELDSETTING, ///< ASN.1 FieldSetting_Type |
| 234 | OT_SELTYPE, ///< another Type (T_SELTYPE), ASN.1 selection type |
| 235 | OT_OCFT, ///< another Type (T_OCFT), ASN.1 obj.class field type |
| 236 | OT_TEMPLATE_INST, ///< a TemplateInstance (TTCN-3) |
| 237 | OT_RUNSON_SCOPE, ///< a RunsOnScope (TTCN-3) |
| 238 | OT_EXC_SPEC, ///< exception Specification (ExcSpec) |
| 239 | OT_SIG_PAR, ///< signature parameter (SignatureParam) |
| 240 | OT_POOL ///< It's a pool type, owned by the type pool |
| 241 | }; |
| 242 | |
| 243 | /** Returns the display string of \a encoding_type. */ |
| 244 | static const char *get_encoding_name(MessageEncodingType_t encoding_type); |
| 245 | /** Returns a pool type that represents the encoded stream of the given |
| 246 | * \a encoding_type. */ |
| 247 | static Type *get_stream_type(MessageEncodingType_t encoding_type); |
| 248 | |
| 249 | enum truth { |
| 250 | No, Maybe, Yes |
| 251 | }; |
| 252 | |
| 253 | private: |
| 254 | typetype_t typetype; |
| 255 | bool tags_checked; |
| 256 | bool tbl_cons_checked; |
| 257 | bool text_checked; |
| 258 | bool json_checked; |
| 259 | bool raw_parsed; |
| 260 | bool raw_checked; |
| 261 | bool xer_checked; |
| 262 | bool raw_length_calculated; |
| 263 | bool has_opentypes; |
| 264 | bool opentype_outermost; |
| 265 | bool code_generated; |
| 266 | bool embed_values_possible; |
| 267 | bool use_nil_possible; |
| 268 | bool use_order_possible; |
| 269 | int raw_length; |
| 270 | Type *parent_type; |
| 271 | Tags *tags; |
| 272 | Constraints *constraints; |
| 273 | /// The type's attributes (with context) |
| 274 | Ttcn::WithAttribPath* w_attrib_path; |
| 275 | /** A copy of all the AT_ENCODEs */ |
| 276 | Ttcn::WithAttribPath* encode_attrib_path; |
| 277 | RawAST *rawattrib; |
| 278 | TextAST *textattrib; |
| 279 | XerAttributes *xerattrib; |
| 280 | BerAST *berattrib; |
| 281 | JsonAST *jsonattrib; |
| 282 | |
| 283 | vector<SubTypeParse> *parsed_restr; ///< parsed subtype restrictions are stored here until they are moved to the sub_type member |
| 284 | SubType *sub_type; ///< effective/aggregate subtype of this type, NULL if neither inherited nor own subtype restrictions exist |
| 285 | |
| 286 | string encoding_str; // needed by codegen for encvalue() and decvalue() |
| 287 | string decoding_str; |
| 288 | bool coding_by_function; // false - coding attribute is set, true - coding via coding function |
| 289 | /** What kind of AST element owns the type. |
| 290 | * It may not be known at creation type, so it's initially OT_UNKNOWN. |
| 291 | * We want this information so we don't have to bother with XER |
| 292 | * if the type is an ASN.1 construct, or it's the type in a "runs on" scope, |
| 293 | * the type of a variable declaration/module par/const, etc. */ |
| 294 | TypeOwner_t ownertype; |
| 295 | Node *owner; |
| 296 | |
| 297 | union { |
| 298 | struct { |
| 299 | Block *block; |
| 300 | NamedValues *nvs; |
| 301 | } namednums; |
| 302 | struct { |
| 303 | EnumItems *eis; ///< Final set of enum items |
| 304 | Int first_unused; ///< First unused >=0 value (for UNKNOWN_VALUE) |
| 305 | Int second_unused; ///< Second unused >=0 value (for UNBOUND_VALUE) |
| 306 | Block *block; ///< ASN.1 block to be parsed |
| 307 | EnumItems *eis1; ///< First set of enum items before the ellipsis |
| 308 | bool ellipsis; ///< true if there was an ellipsis, false otherwise |
| 309 | ExcSpec *excSpec; ///< Exception specification |
| 310 | EnumItems *eis2; ///< Second set of enum items after the ellipsis |
| 311 | map<string, size_t> *eis_by_name; |
| 312 | } enums; |
| 313 | struct { |
| 314 | CompFieldMap *cfm; |
| 315 | Block *block; ///< Unparsed block; will be 0 after parse_block_...() |
| 316 | CTs_EE_CTs *ctss; |
| 317 | bool tr_compsof_ready; |
| 318 | bool component_internal; |
| 319 | map<string, size_t> *field_by_name; |
| 320 | OC_defn *oc_defn; /**< link to... */ |
| 321 | const Identifier *oc_fieldname; /**< link to... */ |
| 322 | const TableConstraint *my_tableconstraint; /**< link to... */ |
| 323 | bool has_single_charenc; /**< Has a single character-encodable field |
| 324 | * with the UNTAGGED encoding instruction. |
| 325 | * X693amd1 32.2.2 applies to the field. */ |
| 326 | } secho; /**< data for T_(SEQUENCE|SET_CHOICE)_[AT] */ |
| 327 | struct { |
| 328 | Type *ofType; |
| 329 | bool component_internal; |
| 330 | } seof; /**< data for SEQUENCE OF/SET OF */ |
| 331 | struct { |
| 332 | Reference *ref; |
| 333 | Type *type_refd; /**< link to... */ |
| 334 | OC_defn *oc_defn; /**< link to... */ |
| 335 | const Identifier *oc_fieldname; /**< link to... */ |
| 336 | bool component_internal; |
| 337 | } ref; |
| 338 | struct { |
| 339 | Identifier *id; |
| 340 | Type *type; |
| 341 | Type *type_refd; |
| 342 | } seltype; |
| 343 | struct { |
| 344 | Type *element_type; |
| 345 | Ttcn::ArrayDimension *dimension; |
| 346 | bool in_typedef; |
| 347 | bool component_internal; |
| 348 | } array; |
| 349 | Ttcn::PortTypeBody *port; |
| 350 | ComponentTypeBody *component; |
| 351 | Type *address; /**< link to... */ |
| 352 | struct { |
| 353 | SignatureParamList *parameters; |
| 354 | Type *return_type; |
| 355 | bool no_block; |
| 356 | bool component_internal; |
| 357 | SignatureExceptions *exceptions; |
| 358 | } signature; |
| 359 | struct { |
| 360 | Ttcn::FormalParList *fp_list; |
| 361 | struct { |
| 362 | bool self; |
| 363 | Ttcn::Reference *ref; |
| 364 | Type *type; // useful only after check |
| 365 | } runs_on; |
| 366 | union { |
| 367 | Type *return_type; |
| 368 | struct { |
| 369 | Ttcn::Reference *ref; |
| 370 | Type *type; // useful only after check |
| 371 | } system; |
| 372 | }; |
| 373 | bool returns_template; |
| 374 | template_restriction_t template_restriction; |
| 375 | bool is_startable; |
| 376 | } fatref; |
| 377 | } u; |
| 378 | static const char* type_as_string[]; |
| 379 | |
| 380 | /** True if chk() has finished running. |
| 381 | * Prevents force_raw() from running chk_raw(), chk_text() or chk_json() on unchecked types. */ |
| 382 | bool chk_finished; |
| 383 | |
| 384 | /** Signifies that this type is an instance of an ASN.1 parameterized type. |
| 385 | * It will not have its own segment and reference generated in the JSON schema, |
| 386 | * its schema segment will be generated as an embedded type's would. */ |
| 387 | bool pard_type_instance; |
| 388 | |
| 389 | /** Copy constructor, for the use of Type::clone() only. */ |
| 390 | Type(const Type& p); |
| 391 | /** Assignment disabled */ |
| 392 | Type& operator=(const Type& p); |
| 393 | /** Set fields to their default values */ |
| 394 | void init(); |
| 395 | /** Free up resources */ |
| 396 | void clean_up(); |
| 397 | /** Returns the default tag of the type. */ |
| 398 | Tag *get_default_tag(); |
| 399 | /** Returns the number in UNIVERSAL tag class that belongs to ASN.1 type |
| 400 | * type \a p_tt. In case of invalid argument -1 is returned */ |
| 401 | static int get_default_tagnumber(typetype_t p_tt); |
| 402 | /** Container for the allocated tags that do not belong to a particular |
| 403 | * Type object */ |
| 404 | static map<typetype_t, Tag> *default_tags; |
| 405 | static void destroy_default_tags(); |
| 406 | /** Container for the allocated pool types */ |
| 407 | static map<typetype_t, Type> *pooltypes; |
| 408 | /** Drops the elements of \a pooltypes */ |
| 409 | static void destroy_pooltypes(); |
| 410 | /** Returns the TTCN-3 equivalent of \a p_tt. */ |
| 411 | static typetype_t get_typetype_ttcn3(typetype_t p_tt); |
| 412 | |
| 413 | public: |
| 414 | /** @name Constructors |
| 415 | * @{ */ |
| 416 | /// Construct a predefined type (including anytype and address) |
| 417 | Type(typetype_t p_tt); |
| 418 | /// Construct a TTCN enumerated type |
| 419 | Type(typetype_t p_tt, EnumItems *p_eis); |
| 420 | /** Construct an ASN.1 enum, sequence, set, choice, integer with |
| 421 | * named numbers, or a bitstring with named bits */ |
| 422 | Type(typetype_t p_tt, Block *p_block); |
| 423 | /// Construct an ASN.1 enum, with or without extension |
| 424 | Type(typetype_t p_tt, |
| 425 | EnumItems *p_eis1, bool p_ellipsis, EnumItems *p_eis2); |
| 426 | /// Construct a TTCN3 sequence, set or choice |
| 427 | Type(typetype_t p_tt, CompFieldMap *p_cfm); |
| 428 | /** Construct a type with an embedded type: a record-of, set-of, |
| 429 | * or a special reference (involved in: ASN.1 table constraint, |
| 430 | * TTCN3 (ext)const definition, module parameter, variable instance) */ |
| 431 | Type(typetype_t p_tt, Type *p_type); |
| 432 | /// Create an ASN.1 selection type |
| 433 | Type(typetype_t p_tt, Identifier *p_id, Type *p_type); |
| 434 | /// ASN.1 ObjectClassFieldType |
| 435 | Type(typetype_t p_tt, Type *p_type, OC_defn *p_oc_defn, |
| 436 | const Identifier *p_id); |
| 437 | /// Create a TTCN3 array |
| 438 | Type(typetype_t p_tt, Type *p_type, Ttcn::ArrayDimension *p_dim, |
| 439 | bool p_in_typedef); |
| 440 | /// Create an ASN.1 open type |
| 441 | Type(typetype_t p_tt, OC_defn *p_oc_defn, const Identifier *p_id); |
| 442 | /// Create a reference |
| 443 | Type(typetype_t p_tt, Reference *p_ref); |
| 444 | /// Create a TTCN3 port type |
| 445 | Type(typetype_t p_tt, Ttcn::PortTypeBody *p_pb); |
| 446 | /// Create a TTCN3 component type |
| 447 | Type(typetype_t p_tt, ComponentTypeBody *p_cb); |
| 448 | /// Create a TTCN3 signature |
| 449 | Type(typetype_t p_tt, SignatureParamList *p_params, Type *p_returntype, |
| 450 | bool p_noblock, SignatureExceptions *p_exceptions); |
| 451 | /// Create a TTCN3 function reference |
| 452 | Type(typetype_t p_tt,Ttcn::FormalParList *p_params, |
| 453 | Ttcn::Reference* p_runs_on_ref, bool p_runs_on_self, |
| 454 | Type *p_returntype, bool p_returns_template, |
| 455 | template_restriction_t p_template_restriction); |
| 456 | /// Create a TTCN3 altstep |
| 457 | Type(typetype_t p_tt,Ttcn::FormalParList *p_params, |
| 458 | Ttcn::Reference* p_runs_on_ref, bool p_runs_on_self); |
| 459 | /// Create a TTCN3 testcase |
| 460 | Type(typetype_t p_tt,Ttcn::FormalParList *p_params, |
| 461 | Ttcn::Reference* p_runs_on_ref, Ttcn::Reference *p_system_ref); |
| 462 | /** @} */ |
| 463 | virtual ~Type(); |
| 464 | /** This function must be called to clean up the pool types, |
| 465 | * tags, etc. It is called by main() */ |
| 466 | static void free_pools(); |
| 467 | /** Create a (partial) copy of the object */ |
| 468 | virtual Type* clone() const; |
| 469 | /** Return the type of type. */ |
| 470 | typetype_t get_typetype() const { return typetype; } |
| 471 | /** Returns the TTCN-3 equivalent of \a typetype. */ |
| 472 | typetype_t get_typetype_ttcn3() const |
| 473 | { return get_typetype_ttcn3(typetype); } |
| 474 | /** Returns a simple/built-in type from the pool */ |
| 475 | static Type* get_pooltype(typetype_t p_typetype); |
| 476 | /** Returns whether the type is defined in an ASN.1 module. */ |
| 477 | bool is_asn1() const; |
| 478 | /** Returns true if it is a type reference. */ |
| 479 | bool is_ref() const; |
| 480 | /** Returns true if it is a Sequence, Set or Choice. */ |
| 481 | bool is_secho() const; |
| 482 | /** Returns true if this is a character-encodable type. |
| 483 | * Being character-encodable is a requirement for a type to be |
| 484 | * encoded as an XML attribute. */ |
| 485 | truth is_charenc(); |
| 486 | /** Return true if at least one abstract value of the type |
| 487 | * has an empty "ExtendedXMLValue" encoding (only possible with EXER). |
| 488 | * Possible for record/set when all components are optional, |
| 489 | * and record-of/set-of when 0 length is not forbidden. */ |
| 490 | bool has_empty_xml(); |
| 491 | /** Returns whether \a this is a sequence-of/record-of or set-of type. */ |
| 492 | bool is_seof() const { return typetype == T_SEQOF || typetype == T_SETOF; } |
| 493 | /** Returns the \a sub_type member */ |
| 494 | SubType* get_sub_type() const { return sub_type; } |
| 495 | /** If this is a reference, returns the referenced type. |
| 496 | * Otherwise, it's a fatal error. */ |
| 497 | Type* get_type_refd(ReferenceChain *refch=0); |
| 498 | /** Walk through all references to the referenced type */ |
| 499 | Type* get_type_refd_last(ReferenceChain *refch=0); |
| 500 | /** Returns the type of the field, which is referenced by \a subrefs from |
| 501 | * \a this. It checks the array indices against \a expected_index. In case |
| 502 | * of error NULL is returned. |
| 503 | * Special case: if \a interrupt_if_optional is true then return NULL if an |
| 504 | * optional field has been reached. Using this bool parameter it can be |
| 505 | * checked if a referenced field is on an optional path (used by template |
| 506 | * restriction checking code) */ |
| 507 | Type *get_field_type(Ttcn::FieldOrArrayRefs *subrefs, |
| 508 | expected_value_t expected_index, ReferenceChain *refch = 0, |
| 509 | bool interrupt_if_optional = false); |
| 510 | /** subrefs must point to an existing field, get_field_type() should be used |
| 511 | * to check. subrefs_array will be filled with the indexes of the fields, |
| 512 | * type_array will be filled with types whose field indexes were collected, |
| 513 | * if an invalid index is encountered false will be returned */ |
| 514 | bool get_subrefs_as_array(const Ttcn::FieldOrArrayRefs *subrefs, |
| 515 | dynamic_array<size_t>& subrefs_array, dynamic_array<Type*>& type_array); |
| 516 | /** Returns whether the last field referenced by \a subrefs is an optional |
| 517 | * record/SEQUENCE or set/SET field. It can be used only after a successful |
| 518 | * semantic check (e.g. during code generation) or the behaviour will be |
| 519 | * unpredictable. */ |
| 520 | bool field_is_optional(Ttcn::FieldOrArrayRefs *subrefs); |
| 521 | /** Returns whether this type instance is the type of an optional field. */ |
| 522 | bool is_optional_field() const; |
| 523 | virtual void set_fullname(const string& p_fullname); |
| 524 | /** Sets the internal pointer my_scope to \a p_scope. */ |
| 525 | virtual void set_my_scope(Scope *p_scope); |
| 526 | /** Checks the type (including tags). */ |
| 527 | virtual void chk(); |
| 528 | /** Return whether the two typetypes are compatible. Sometimes, this is |
| 529 | * just a question of \p p_tt1 == \p p_tt2. When there are multiple |
| 530 | * typetypes for a type (e.g. T_ENUM_A and T_ENUM_T) then all |
| 531 | * combinations of those are compatible. */ |
| 532 | static bool is_compatible_tt_tt(typetype_t p_tt1, typetype_t p_tt2, |
| 533 | bool p_is_asn11, bool p_is_asn12); |
| 534 | /** Returns whether the type is compatible with \a p_tt. Used if the |
| 535 | * other value is unfoldable, but we can determine its expr_typetype. |
| 536 | * Note: The compatibility relation is asymmetric. The function returns |
| 537 | * true if the set of possible values in \a p_type is a subset of |
| 538 | * possible values in \a this. */ |
| 539 | bool is_compatible_tt(typetype_t p_tt, bool p_is_asn1); |
| 540 | /** Returns whether this type is compatible with \a p_type. Note: The |
| 541 | * compatibility relation is asymmetric. The function returns true if |
| 542 | * the set of possible values in \a p_type is a subset of possible values |
| 543 | * in \a this. It returns false if the two types cannot be compatible |
| 544 | * ever. If the two types are compatible, but they need additional |
| 545 | * "type" conversion code generated with run-time checks \p p_info will |
| 546 | * provide more information. \p p_info is used to collect type |
| 547 | * information to report more precise errors. \p p_left_chain and |
| 548 | * \p p_right_chain are there to prevent infinite recursion. |
| 549 | * \p p_left_chain contains the type chain of the left operand from the |
| 550 | * "root" type to this point in the type's structure. \p p_right_chain |
| 551 | * is the same for the right operand. */ |
| 552 | bool is_compatible(Type *p_type, TypeCompatInfo *p_info, |
| 553 | TypeChain *p_left_chain = NULL, |
| 554 | TypeChain *p_right_chain = NULL); |
| 555 | /** Check if the restrictions of a T_SEQOF/T_SETOF are "compatible" with |
| 556 | * the given type \a p_type. Can be called only as a T_SEQOF/T_SETOF. |
| 557 | * Currently, used for structured types only. \a p_type can be any kind |
| 558 | * of structured type. */ |
| 559 | bool is_subtype_length_compatible(Type *p_type); |
| 560 | /** Check if it's a structured type. Return true if the current type is a |
| 561 | * structured type, false otherwise. */ |
| 562 | bool is_structured_type() const; |
| 563 | /** returns the type as a string */ |
| 564 | virtual const char* asString() const; |
| 565 | static const char* asString(typetype_t type); |
| 566 | |
| 567 | private: |
| 568 | /** Helper functions for is_compatible(). These functions can be called |
| 569 | * only for a Type that the name suggests. \p p_type is the Type we're |
| 570 | * checking compatibility against. \p p_info is used to collect type |
| 571 | * information to report more precise errors. \p p_left_chain and |
| 572 | * \p p_right_chain are there to prevent infinite recursion. |
| 573 | * \p p_left_chain contains the type chain of the left operand from the |
| 574 | * "root" type to this point in the type's structure. \p p_right_chain |
| 575 | * is the same for the right operand. */ |
| 576 | bool is_compatible_record(Type *p_type, TypeCompatInfo *p_info, |
| 577 | TypeChain *p_left_chain = NULL, |
| 578 | TypeChain *p_right_chain = NULL); |
| 579 | bool is_compatible_record_of(Type *p_type, TypeCompatInfo *p_info, |
| 580 | TypeChain *p_left_chain = NULL, |
| 581 | TypeChain *p_right_chain = NULL); |
| 582 | bool is_compatible_set(Type *p_type, TypeCompatInfo *p_info, |
| 583 | TypeChain *p_left_chain = NULL, |
| 584 | TypeChain *p_right_chain = NULL); |
| 585 | bool is_compatible_set_of(Type *p_type, TypeCompatInfo *p_info, |
| 586 | TypeChain *p_left_chain = NULL, |
| 587 | TypeChain *p_right_chain = NULL); |
| 588 | bool is_compatible_array(Type *p_type, TypeCompatInfo *p_info, |
| 589 | TypeChain *p_left_chain = NULL, |
| 590 | TypeChain *p_right_chain = NULL); |
| 591 | bool is_compatible_choice_anytype(Type *p_type, TypeCompatInfo *p_info, |
| 592 | TypeChain *p_left_chain = NULL, |
| 593 | TypeChain *p_right_chain = NULL); |
| 594 | public: |
| 595 | /** Returns whether this type is identical to \a p_type from TTCN-3 point |
| 596 | * of view. Note: This relation is symmetric. The function returns true |
| 597 | * only if the sets of possible values are the same in both types. */ |
| 598 | bool is_identical(Type *p_type); |
| 599 | /** Tasks: Decides whether the type needs automatic tagging, performs the |
| 600 | * COMPONENTS OF transformations (recursively) and adds the automatic |
| 601 | * tags. */ |
| 602 | void tr_compsof(ReferenceChain *refch = 0); |
| 603 | /** Returns whether the T_FUNCTION is startable. |
| 604 | * @pre typetype is T_FUNCTION, or else FATAL_ERROR occurs. */ |
| 605 | bool is_startable(); |
| 606 | |
| 607 | /** Returns true if this is a list type (string, rec.of, set.of or array */ |
| 608 | bool is_list_type(bool allow_array); |
| 609 | |
| 610 | void chk_coding(bool encode); |
| 611 | bool is_coding_by_function() const; |
| 612 | const string& get_coding(bool encode) const; |
| 613 | private: |
| 614 | static MessageEncodingType_t get_enc_type(const Ttcn::SingleWithAttrib& enc); |
| 615 | |
| 616 | void chk_Int_A(); |
| 617 | void chk_Enum_A(); |
| 618 | void chk_Enum_item(EnumItem *ei, bool after_ellipsis, |
| 619 | map<Int, EnumItem>& value_map); |
| 620 | void chk_Enum_T(); |
| 621 | void chk_BStr_A(); |
| 622 | void chk_SeCho_T(); |
| 623 | void chk_Choice_A(); |
| 624 | void chk_Se_A(); |
| 625 | void chk_SeOf(); |
| 626 | void chk_refd(); |
| 627 | void chk_seltype(); |
| 628 | void chk_Array(); |
| 629 | void chk_Signature(); |
| 630 | void chk_Fat(); |
| 631 | public: |
| 632 | /** Checks whether the type can be the TTCN-3 address type. Not allowed: |
| 633 | * the default type, references pointing to port types, component types |
| 634 | * and signatures */ |
| 635 | void chk_address(); |
| 636 | /** Checks whether the type can be a component of another type definition |
| 637 | * (e.g. field of a structured type, parameter/return type/exception of a |
| 638 | * signature). |
| 639 | * Not allowed types: ports, signatures. |
| 640 | * Default type is allowed only within structured types. |
| 641 | * The text for the end of the error message is passed as parameter. |
| 642 | */ |
| 643 | void chk_embedded(bool default_allowed, const char *error_msg); |
| 644 | /** Checks for circular references within embedded types */ |
| 645 | void chk_recursions(ReferenceChain& refch); |
| 646 | /** Checks that the structured type does not have fields |
| 647 | * with the name of its definition. |
| 648 | */ |
| 649 | void chk_constructor_name(const Identifier& p_id); |
| 650 | bool chk_startability(); |
| 651 | /** Checks if it can be a return type */ |
| 652 | void chk_as_return_type(bool as_value, const char* what); |
| 653 | private: |
| 654 | void parse_block_Int(); |
| 655 | void parse_block_Enum(); |
| 656 | void parse_block_BStr(); |
| 657 | void parse_block_Choice(); |
| 658 | void parse_block_Se(); |
| 659 | int get_length_multiplier(); |
| 660 | void parse_attributes(); |
| 661 | void chk_raw(); |
| 662 | /** If the type does not have a rawattrib, create one. */ |
| 663 | void force_raw(); |
| 664 | void chk_text(); |
| 665 | void chk_text_matching_values(textAST_matching_values *matching_values, |
| 666 | const char *attrib_name); |
| 667 | /** If the type does not have a textattrib, create one. */ |
| 668 | void force_text(); |
| 669 | |
| 670 | void chk_json(); |
| 671 | void chk_json_default(); |
| 672 | /** If the type does not have a jsonattrib, create one. */ |
| 673 | void force_json(); |
| 674 | |
| 675 | void chk_xer(); |
| 676 | void chk_xer_any_attributes(); |
| 677 | void chk_xer_any_element(); |
| 678 | void chk_xer_attribute(); |
| 679 | void chk_xer_dfe(); |
| 680 | Value *new_value_for_dfe(Type *last, const char *dfe_str); |
| 681 | void target_of_text(string& text); |
| 682 | void chk_xer_embed_values(int num_attributes); |
| 683 | void chk_xer_text(); |
| 684 | void chk_xer_untagged(); |
| 685 | void chk_xer_use_nil(); |
| 686 | void chk_xer_use_order(int num_attributes); |
| 687 | void chk_xer_use_type(); |
| 688 | void chk_xer_use_union(); |
| 689 | |
| 690 | bool is_root_basic(); |
| 691 | int get_raw_length(); |
| 692 | public: |
| 693 | void set_parent_type(Type *p_parent_type) {parent_type=p_parent_type;} |
| 694 | Type* get_parent_type() const {return parent_type;} |
| 695 | void set_has_opentypes() {has_opentypes=true;} |
| 696 | bool get_has_opentypes() const {return has_opentypes;} |
| 697 | void set_opentype_outermost() {opentype_outermost=true;} |
| 698 | bool get_is_opentype_outermost() const {return opentype_outermost;} |
| 699 | /** If \a value is an undef lowerid, then this member decides |
| 700 | * whether it is a reference or a lowerid value (e.g., enum, named |
| 701 | * number). */ |
| 702 | void chk_this_value_ref(Value *value); |
| 703 | bool chk_this_value(Value *value, Common::Assignment *lhs, |
| 704 | expected_value_t expected_value, namedbool incomplete_allowed, |
| 705 | namedbool omit_allowed, namedbool sub_chk, |
| 706 | namedbool implicit_omit = NOT_IMPLICIT_OMIT, |
| 707 | namedbool str_elem = NOT_STR_ELEM); |
| 708 | /** Checks the given referenced value */ |
| 709 | bool chk_this_refd_value(Value *value, Common::Assignment *lhs, |
| 710 | expected_value_t expected_value, ReferenceChain *refch=0, |
| 711 | namedbool str_elem = NOT_STR_ELEM); |
| 712 | /** Checks the given invocation */ |
| 713 | void chk_this_invoked_value(Value *value, Common::Assignment *lhs, |
| 714 | expected_value_t expected_value); |
| 715 | private: |
| 716 | void chk_this_value_Null(Value *value); |
| 717 | void chk_this_value_Bool(Value *value); |
| 718 | void chk_this_value_Int(Value *value); |
| 719 | void chk_this_value_Int_A(Value *value); |
| 720 | void chk_this_value_Real(Value *value); |
| 721 | void chk_this_value_Enum(Value *value); |
| 722 | void chk_this_value_BStr(Value *value); |
| 723 | void chk_this_value_namedbits(Value *value); |
| 724 | void chk_this_value_BStr_A(Value *value); |
| 725 | void chk_this_value_HStr(Value *value); |
| 726 | void chk_this_value_OStr(Value *value); |
| 727 | void chk_this_value_CStr(Value *value); |
| 728 | void chk_this_value_OID(Value *value); |
| 729 | void chk_this_value_ROID(Value *value); |
| 730 | void chk_this_value_Any(Value *value); |
| 731 | bool chk_this_value_Choice(Value *value, Common::Assignment *lhs, |
| 732 | expected_value_t expected_value, namedbool incomplete_allowed, |
| 733 | namedbool implicit_omit = NOT_IMPLICIT_OMIT); |
| 734 | bool chk_this_value_Se(Value *value, Common::Assignment *lhs, |
| 735 | expected_value_t expected_value, namedbool incomplete_allowed, |
| 736 | namedbool implicit_omit = NOT_IMPLICIT_OMIT); |
| 737 | bool chk_this_value_Se_T(Value *value, Common::Assignment *lhs, |
| 738 | expected_value_t expected_value, namedbool incomplete_allowed, |
| 739 | namedbool implicit_omit = NOT_IMPLICIT_OMIT); |
| 740 | bool chk_this_value_Seq_T(Value *value, Common::Assignment *lhs, |
| 741 | expected_value_t expected_value, namedbool incomplete_allowed, |
| 742 | namedbool implicit_omit = NOT_IMPLICIT_OMIT); |
| 743 | bool chk_this_value_Set_T(Value *value, Common::Assignment *lhs, |
| 744 | expected_value_t expected_value, namedbool incomplete_allowed, |
| 745 | namedbool implicit_omit = NOT_IMPLICIT_OMIT); |
| 746 | bool chk_this_value_Se_A(Value *value, Common::Assignment *lhs, |
| 747 | expected_value_t expected_value, namedbool implicit_omit); |
| 748 | bool chk_this_value_Seq_A(Value *value, Common::Assignment *lhs, |
| 749 | expected_value_t expected_value, namedbool implicit_omit); |
| 750 | bool chk_this_value_Set_A(Value *value, Common::Assignment *lhs, |
| 751 | expected_value_t expected_value, namedbool implicit_omit); |
| 752 | bool chk_this_value_SeOf(Value *value, Common::Assignment *lhs, |
| 753 | expected_value_t expected_value, namedbool incomplete_allowed, |
| 754 | namedbool implicit_omit = NOT_IMPLICIT_OMIT); |
| 755 | void chk_this_value_Verdict(Value *value); |
| 756 | void chk_this_value_Default(Value *value); |
| 757 | bool chk_this_value_Array(Value *value, Common::Assignment *lhs, |
| 758 | expected_value_t expected_value, namedbool incomplete_allowed, |
| 759 | namedbool implicit_omit); |
| 760 | bool chk_this_value_Signature(Value *value, Common::Assignment *lhs, |
| 761 | expected_value_t expected_value, namedbool incomplete_allowed); |
| 762 | void chk_this_value_Component(Value *value); |
| 763 | void chk_this_value_FAT(Value *value); |
| 764 | public: |
| 765 | /** Checks whether template \a t is a specific value and the embedded value |
| 766 | * is a referenced one. If the reference in the value points to a |
| 767 | * template-like entity then it sets the template type to TEMPLATE_REFD, |
| 768 | * otherwise it leaves everything as is. */ |
| 769 | void chk_this_template_ref(Template *t); |
| 770 | /** Checks for self references in functions returning templates (external or otherwise) |
| 771 | * and in parametrised templates. Returns true if the reference in assignment \a lhs |
| 772 | * is found. |
| 773 | * Recursive: calls itself incase of multiple embedded functions / parametrised templates.*/ |
| 774 | bool chk_this_template_ref_pard(Ttcn::Ref_pard* ref_pard, Common::Assignment* lhs); |
| 775 | bool chk_this_template_generic(Template *t, namedbool incomplete_allowed, |
| 776 | namedbool allow_omit, namedbool allow_any_or_omit, namedbool sub_chk, |
| 777 | namedbool implicit_omit, Common::Assignment *lhs); |
| 778 | private: |
| 779 | bool chk_this_refd_template(Template *t, Common::Assignment *lhs); |
| 780 | void chk_this_template_length_restriction(Template *t); |
| 781 | bool chk_this_template(Template *t, namedbool is_modified, namedbool sub_chk, |
| 782 | namedbool implicit_omit, Common::Assignment *); |
| 783 | void chk_this_template_Str(Template *t); |
| 784 | /** Checks whether \a v is a correct range boundary for this type. |
| 785 | * Applicable to the following types: integer, float, charstring, |
| 786 | * universal charstring. |
| 787 | * Argument \a v might be NULL in case of + or - infinity. |
| 788 | * Argument \a which shall contain the word "lower" or "upper". |
| 789 | * Argument \a loc is used for error reporting if \a v is NULL (it points |
| 790 | * to the surrounding template). |
| 791 | * If \a v is correct and it is or refers to a constant the constant value |
| 792 | * is returned for further checking. Otherwise the return value is NULL. */ |
| 793 | Value *chk_range_boundary(Value *v, const char *which, const Location& loc); |
| 794 | void chk_range_boundary_infinity(Value *v, bool is_upper); |
| 795 | void chk_this_template_builtin(Template *t); |
| 796 | void chk_this_template_Int_Real(Template *t); |
| 797 | void chk_this_template_Enum(Template *t); |
| 798 | bool chk_this_template_Choice(Template *t, namedbool is_modified, |
| 799 | namedbool implicit_omit, Common::Assignment *lhs); |
| 800 | bool chk_this_template_Seq(Template *t, namedbool is_modified, |
| 801 | namedbool implicit_omit, Common::Assignment *lhs); |
| 802 | bool chk_this_template_Set(Template *t, namedbool is_modified, |
| 803 | namedbool implicit_omit, Common::Assignment *lhs); |
| 804 | bool chk_this_template_SeqOf(Template *t, namedbool is_modified, |
| 805 | namedbool implicit_omit, Common::Assignment *lhs); |
| 806 | bool chk_this_template_SetOf(Template *t, namedbool is_modified, |
| 807 | namedbool implicit_omit, Common::Assignment *lhs); |
| 808 | bool chk_this_template_array(Template *t, namedbool is_modified, |
| 809 | namedbool implicit_omit, Common::Assignment *lhs); |
| 810 | void chk_this_template_Fat(Template *t); |
| 811 | void chk_this_template_Signature(Template *t, namedbool is_modified); |
| 812 | public: |
| 813 | /** Check whether there is an enum item with the given name. |
| 814 | * |
| 815 | * @pre typetype is T_ENUM_T or T_ENUM_A */ |
| 816 | bool has_ei_withName(const Identifier& p_id) const; |
| 817 | |
| 818 | /** Return the enum item with the given name. |
| 819 | * |
| 820 | * @pre typetype is T_ENUM_T or T_ENUM_A */ |
| 821 | EnumItem *get_ei_byName(const Identifier& p_id) const; |
| 822 | |
| 823 | /** Return the enum item with the given index. |
| 824 | * |
| 825 | * @pre typetype is T_ENUM_T or T_ENUM_A */ |
| 826 | EnumItem *get_ei_byIndex(size_t i) const; |
| 827 | |
| 828 | /** Get the number of components. |
| 829 | * |
| 830 | * @return the number of components from the appropriate alternative |
| 831 | * depending on the \a typetype. |
| 832 | * |
| 833 | * @pre \a typetype is one of T_CHOICE_T, T_SEQ_T, T_SET_T, T_OPENTYPE, |
| 834 | * T_SEQ_A, T_SET_A, T_CHOICE_A, T_ARRAY, T_SIGNATURE, T_ANYTYPE */ |
| 835 | size_t get_nof_comps(); |
| 836 | |
| 837 | /** Get the name (id) of the component with the given index. |
| 838 | * |
| 839 | * @pre \a typetype is one of T_CHOICE_T, T_SEQ_T, T_SET_T, T_OPENTYPE, |
| 840 | * T_SEQ_A, T_SET_A, T_CHOICE_A, T_SIGNATURE, T_ANYTYPE |
| 841 | * |
| 842 | * @note Not valid for T_ARRAY */ |
| 843 | const Identifier& get_comp_id_byIndex(size_t n); |
| 844 | |
| 845 | /** Get the component with the given index. |
| 846 | * |
| 847 | * @pre \a typetype is one of T_CHOICE_T, T_SEQ_T, T_SET_T, T_OPENTYPE, |
| 848 | * T_SEQ_A, T_SET_A, T_CHOICE_A, T_ANYTYPE |
| 849 | * |
| 850 | * @note Not valid for T_ARRAY or T_SIGNATURE */ |
| 851 | CompField* get_comp_byIndex(size_t n); |
| 852 | |
| 853 | /** Get the index of the component with the given name |
| 854 | * |
| 855 | * @pre \a typetype of the last referenced type is one of |
| 856 | * T_CHOICE_T, T_SEQ_T, T_SET_T, T_OPENTYPE, |
| 857 | * T_SEQ_A, T_SET_A, T_CHOICE_A, T_ANYTYPE */ |
| 858 | size_t get_comp_index_byName(const Identifier& p_name); |
| 859 | |
| 860 | /** Get the index of the enum item with the given name |
| 861 | * |
| 862 | * @pre typetype is T_ENUM_T or T_ENUM_A */ |
| 863 | size_t get_eis_index_byName(const Identifier& p_name); |
| 864 | |
| 865 | const Int& get_enum_val_byId(const Identifier& p_name); |
| 866 | |
| 867 | size_t get_nof_root_comps(); |
| 868 | CompField* get_root_comp_byIndex(size_t n); |
| 869 | |
| 870 | /** Get the name (id) of the component with the given index. |
| 871 | * |
| 872 | * @pre \a typetype is one of T_CHOICE_T, T_SEQ_T, T_SET_T, T_OPENTYPE, |
| 873 | * T_SEQ_A, T_SET_A, T_CHOICE_A, T_SIGNATURE, T_ANYTYPE |
| 874 | * |
| 875 | * @note Not valid for T_ARRAY */ |
| 876 | bool has_comp_withName(const Identifier& p_name); |
| 877 | CompField* get_comp_byName(const Identifier& p_name); |
| 878 | void add_comp(CompField *p_cf); |
| 879 | |
| 880 | /** Returns the embedded type of 'sequence/record of', 'set of' or array |
| 881 | * types. */ |
| 882 | Type *get_ofType(); |
| 883 | |
| 884 | OC_defn* get_my_oc(); |
| 885 | const Identifier& get_oc_fieldname(); |
| 886 | void set_my_tableconstraint(const TableConstraint *p_tc); |
| 887 | const TableConstraint* get_my_tableconstraint(); |
| 888 | |
| 889 | /** Returns the array dimension. Applicable only if typetype == T_ARRAY. */ |
| 890 | Ttcn::ArrayDimension *get_dimension() const; |
| 891 | |
| 892 | /** Returns the PortTypeBody if typetype == T_PORT */ |
| 893 | Ttcn::PortTypeBody *get_PortBody() const; |
| 894 | |
| 895 | /** Returns the ComponentTypeBody if typetype == T_COMPONENT */ |
| 896 | ComponentTypeBody *get_CompBody() const; |
| 897 | |
| 898 | /** Returns the parameters of a signature. |
| 899 | * Applicable only if typetype == T_SIGNATURE. */ |
| 900 | SignatureParamList *get_signature_parameters() const; |
| 901 | /** Returns the parameters of a signature. |
| 902 | * Applicable only if typetype == T_SIGNATURE. */ |
| 903 | SignatureExceptions *get_signature_exceptions() const; |
| 904 | /** Returns the return type of a signature. |
| 905 | * Applicable only if typetype == T_SIGNATURE. */ |
| 906 | Type *get_signature_return_type() const; |
| 907 | /** Returns whether the type is a non-blocking signature. |
| 908 | * Applicable only if typetype == T_SIGNATURE. */ |
| 909 | bool is_nonblocking_signature() const; |
| 910 | /** Returns the parameters of a functionreference |
| 911 | * Applicable only if typetype == T_FUNCTION or T_ALTSTEP or T_TESTCASE */ |
| 912 | Ttcn::FormalParList *get_fat_parameters(); |
| 913 | /** Returns the return type of a functionreference |
| 914 | * Applicable only if typetype == T_FUNCTION */ |
| 915 | Type *get_function_return_type(); |
| 916 | /** Returns the runs on type of a functionreference |
| 917 | * Appliacable only if typetype == T_FUNCTION or T_ALTSTEP or T_TESTCASE */ |
| 918 | Type *get_fat_runs_on_type(); |
| 919 | /** Returns if a functionreference 'runs on self' |
| 920 | * Appliacable only if typetype == T_FUNCTION or T_ALTSTEP or T_TESTCASE */ |
| 921 | bool get_fat_runs_on_self(); |
| 922 | /** Applicable only if typetype == T_FUNCTION */ |
| 923 | bool get_returns_template(); |
| 924 | |
| 925 | /** Retruns true if it is a tagged type.*/ |
| 926 | bool is_tagged() const {return tags!=0;} |
| 927 | void add_tag(Tag *p_tag); |
| 928 | bool is_constrained() const {return constraints!=0;} |
| 929 | void add_constraints(Constraints *p_constraints); |
| 930 | Constraints* get_constraints() const {return constraints;} |
| 931 | Reference * get_Reference(); |
| 932 | private: |
| 933 | void chk_table_constraints(); |
| 934 | public: |
| 935 | /** Returns true if the type has multiple alternative tags |
| 936 | * (i.e. it is a non-tagged CHOICE type). */ |
| 937 | bool has_multiple_tags(); |
| 938 | /** Returns the tag of type. If this type is tagged, then the |
| 939 | * outermost tag is returned. */ |
| 940 | Tag *get_tag(); |
| 941 | void get_tags(TagCollection& coll, map<Type*, void>& chain); |
| 942 | /** Returns the smallest possible tag. If !has_multiple_tags() |
| 943 | * then returns get_tag(). Used is SET CER encoding, see X.690 |
| 944 | * 9.3... */ |
| 945 | Tag *get_smallest_tag(); |
| 946 | /** Returns whether the type needs explicit tagging. */ |
| 947 | bool needs_explicit_tag(); |
| 948 | /** Removes the tag(s) from the type that was added during |
| 949 | * automatic tagging transformation. Needed for the implementation |
| 950 | * of COMPONENTS OF transformation. */ |
| 951 | void cut_auto_tags(); |
| 952 | Tags* build_tags_joined(Tags *p_tags=0); |
| 953 | void set_with_attr(Ttcn::MultiWithAttrib* p_attrib); |
| 954 | void set_parent_path(Ttcn::WithAttribPath* p_path); |
| 955 | Ttcn::WithAttribPath* get_attrib_path() const; |
| 956 | bool hasRawAttrs(); |
| 957 | bool hasNeedofRawAttrs(); |
| 958 | bool hasNeedofTextAttrs(); |
| 959 | bool hasNeedofJsonAttrs(); |
| 960 | bool hasNeedofXerAttrs(); |
| 961 | bool hasVariantAttrs(); |
| 962 | /** Returns whether the type has the encoding attribute specified by |
| 963 | * the parameter (either in its own 'with' statement or in the module's) */ |
| 964 | bool hasEncodeAttr(const MessageEncodingType_t encoding_type); |
| 965 | /** Returns whether \a this can be encoded according to rules |
| 966 | * \a p_encoding. |
| 967 | * @note Should be called only during code generation, after the entire |
| 968 | * AST has been checked, or else the compiler might choke on code like: |
| 969 | * type MyRecordOfType[-] ElementTypeAlias; */ |
| 970 | bool has_encoding(const MessageEncodingType_t encoding_type); |
| 971 | /** Generates the C++ equivalent class(es) of the type. */ |
| 972 | void generate_code(output_struct *target); |
| 973 | size_t get_codegen_index(size_t index); |
| 974 | private: |
| 975 | /** Generates code for the case when the C++ classes are implemented by |
| 976 | * hand, includes the header file with name sourcefile and extension hh |
| 977 | */ |
| 978 | void generate_code_include(const string& sourcefile, output_struct *target); |
| 979 | /** Generates code for the embedded types the C++ classes of which must be |
| 980 | * placed before the classes of this type (e.g. the types of mandatory |
| 981 | * record/set fields). */ |
| 982 | void generate_code_embedded_before(output_struct *target); |
| 983 | /** Generates code for the embedded types the C++ classes of which can be |
| 984 | * placed after the classes of this type (e.g. the types of union fields |
| 985 | * and optional record/set fields). */ |
| 986 | void generate_code_embedded_after(output_struct *target); |
| 987 | void generate_code_typedescriptor(output_struct *target); |
| 988 | void generate_code_berdescriptor(output_struct *target); |
| 989 | void generate_code_rawdescriptor(output_struct *target); |
| 990 | void generate_code_textdescriptor(output_struct *target); |
| 991 | void generate_code_jsondescriptor(output_struct *target); |
| 992 | void generate_code_xerdescriptor(output_struct *target); |
| 993 | void generate_code_alias(output_struct *target); |
| 994 | void generate_code_Enum(output_struct *target); |
| 995 | void generate_code_Choice(output_struct *target); |
| 996 | Opentype_t *generate_code_ot(stringpool& pool); |
| 997 | void free_code_ot(Opentype_t* p_ot); |
| 998 | void generate_code_Se(output_struct *target); |
| 999 | void generate_code_SeOf(output_struct *target); |
| 1000 | void generate_code_Array(output_struct *target); |
| 1001 | void generate_code_Fat(output_struct *target); |
| 1002 | void generate_code_Signature(output_struct *target); |
| 1003 | /** Returns whether the type needs an explicit C++ typedef alias and/or |
| 1004 | * an alias to a type descriptor of another type. It returns true for those |
| 1005 | * types that are defined in module-level type definitions hence are |
| 1006 | * directly accessible by the users of C++ API (in test ports, external |
| 1007 | * functions). */ |
| 1008 | bool needs_alias(); |
| 1009 | /** Returns whether this is a pure referenced type that has no tags or |
| 1010 | * encoding attributes. */ |
| 1011 | bool is_pure_refd(); |
| 1012 | void generate_code_done(output_struct *target); |
| 1013 | |
| 1014 | /** Helper function used in generate_code_ispresentbound() for the |
| 1015 | ispresent() function in case of template parameter. Returns true |
| 1016 | if the referenced field which is embedded into a "?" is always present, |
| 1017 | otherwise returns false. **/ |
| 1018 | bool ispresent_anyvalue_embedded_field(Type* t, |
| 1019 | Ttcn::FieldOrArrayRefs *subrefs, size_t begin_index); |
| 1020 | public: |
| 1021 | /** Generates type specific call for the reference used in isbound call |
| 1022 | * into argument \a expr. Argument \a subrefs holds the reference path |
| 1023 | * that needs to be checked. Argument \a module is the actual module of |
| 1024 | * the reference and is used to gain access to temporal identifiers. |
| 1025 | * Argument \a global_id is the name of the bool variable where the result |
| 1026 | * of the isbound check is calculated. Argument \a external_id is the name |
| 1027 | * of the assignment where the call chain starts. |
| 1028 | * Argument \a is_template tells if the assignment is a template or not. |
| 1029 | * Argument \a isbound tells if the function is isbound or ispresent. |
| 1030 | */ |
| 1031 | void generate_code_ispresentbound(expression_struct *expr, |
| 1032 | Ttcn::FieldOrArrayRefs *subrefs, Common::Module* module, |
| 1033 | const string& global_id, const string& external_id, |
| 1034 | const bool is_template, const bool isbound); |
| 1035 | |
| 1036 | /** Extension attribute for optimized code generation of structured types: |
| 1037 | * with { extension "optimize:xxx" } |
| 1038 | * xxx tells what to optimize for (e.g.: memory, performance, etc.) |
| 1039 | * returns empty if none given |
| 1040 | */ |
| 1041 | string get_optimize_attribute(); |
| 1042 | /** Extension attribute for hand written TTCN-3 types: |
| 1043 | * with { extension "sourcefile:xxx" } |
| 1044 | * filename is xxx, source files: xxx.hh and xxx.cc |
| 1045 | * returns empty if none given |
| 1046 | */ |
| 1047 | string get_sourcefile_attribute(); |
| 1048 | bool has_done_attribute(); |
| 1049 | /** Generates the declaration and definition of a C++ value or template |
| 1050 | * object governed by \a this into \a cdef. Argument \a p_scope points to |
| 1051 | * the scope of the object to be generated. Argument \a name contains the |
| 1052 | * identifier of the target C++ object. If argument \a prefix is not NULL |
| 1053 | * the real object will be generated as static, its name will be |
| 1054 | * prefixed with \a prefix and a const (read-only) reference will be |
| 1055 | * exported with name \a name. This function shall be used when there is no |
| 1056 | * Value or Template object in the AST (e.g. in case of variables). */ |
| 1057 | void generate_code_object(const_def *cdef, Scope* p_scope, |
| 1058 | const string& name, const char *prefix, bool is_template); |
| 1059 | /** Generates the declaration and definition of a C++ value or template |
| 1060 | * object governed by \a this into \a cdef based on the attributes of |
| 1061 | * \a p_setting. */ |
| 1062 | void generate_code_object(const_def *cdef, GovernedSimple *p_setting); |
| 1063 | private: |
| 1064 | virtual string create_stringRepr(); |
| 1065 | public: |
| 1066 | /** If this type is added to an opentype, then this name is used |
| 1067 | * as the name of the alternative. */ |
| 1068 | Identifier get_otaltname(bool& is_strange); |
| 1069 | /** Returns the name of the C++ value class that represents \a this at |
| 1070 | * runtime. The class is either pre-defined (written manually in the Base |
| 1071 | * Library) or generated by the compiler. The reference is valid in the |
| 1072 | * module that \a p_scope belongs to. */ |
| 1073 | string get_genname_value(Scope *p_scope); |
| 1074 | /** Returns the name of the C++ class that represents \a this template at |
| 1075 | * runtime. The class is either pre-defined (written manually in the Base |
| 1076 | * Library) or generated by the compiler. The reference is valid in the |
| 1077 | * module that \a p_scope belongs to. */ |
| 1078 | string get_genname_template(Scope *p_scope); |
| 1079 | /** Returns a C++ identifier that can be used to distinguish the type in |
| 1080 | * the union that carries signature exceptions. */ |
| 1081 | string get_genname_altname(); |
| 1082 | /** User visible (not code generator) type name */ |
| 1083 | string get_typename(); |
| 1084 | /** User visible type name for built-in types */ |
| 1085 | static const char * get_typename_builtin(typetype_t tt); |
| 1086 | string get_genname_typedescriptor(Scope *p_scope); |
| 1087 | private: |
| 1088 | /** Returns the name prefix of type descriptors, etc. that belong to the |
| 1089 | * equivalent C++ class referenced from the module of scope \a p_scope. |
| 1090 | * It differs from \a get_genname() only in case of special ASN.1 types |
| 1091 | * like RELATIVE-OID or various string types. */ |
| 1092 | string get_genname_typename(Scope *p_scope); |
| 1093 | /** Return the name of the BER descriptor structure. |
| 1094 | * It is either the name of the type itself; |
| 1095 | * one of "ENUMERATED", "CHOICE", "SEQUENCE", "SET"; |
| 1096 | * or one of the core classes e.g. ASN_ROID, UTF8String, etc. |
| 1097 | * The _ber_ suffix needs to be appended by the caller. */ |
| 1098 | string get_genname_berdescriptor(); |
| 1099 | string get_genname_rawdescriptor(); |
| 1100 | string get_genname_textdescriptor(); |
| 1101 | string get_genname_xerdescriptor(); |
| 1102 | string get_genname_jsondescriptor(); |
| 1103 | /** Return the ASN base type to be written into the type descriptor */ |
| 1104 | const char* get_genname_typedescr_asnbasetype(); |
| 1105 | /** parse subtype information and add parent's subtype information to |
| 1106 | create the effective/aggregate subtype of this type */ |
| 1107 | void check_subtype_constraints(); |
| 1108 | public: |
| 1109 | /** Return the type of subtype that is associated with this type */ |
| 1110 | SubtypeConstraint::subtype_t get_subtype_type(); |
| 1111 | virtual void dump(unsigned level) const; |
| 1112 | void set_parsed_restrictions(vector<SubTypeParse> *stp); |
| 1113 | /** Returns true if the values of this type can be used only in 'self'. |
| 1114 | * Some types (default, function reference with 'runs on self') are |
| 1115 | * invalid outside of the component they were created in, they should not |
| 1116 | * be sent/received in ports or used in compref.start(). All structured |
| 1117 | * types that may contain such internal types are also internal. */ |
| 1118 | bool is_component_internal(); |
| 1119 | /** Prints error messages for types that cannot leave the component. |
| 1120 | * Should be called only if is_component_internal() returned true. |
| 1121 | * \a type_chain is used to escape infinite recursion by maintaining a |
| 1122 | * chain of structured types that call this function recursively, |
| 1123 | * \a p_what tells what is the reason of the error. */ |
| 1124 | void chk_component_internal(map<Type*,void>& type_chain, |
| 1125 | const char* p_what); |
| 1126 | /** Prints error messages for type that cannot be a type of given ones (parameter: array of typetype_t) |
| 1127 | * \a type_chain is used to escape infinite recursion by maintaining a |
| 1128 | * chain of structured types that call this function recursively, |
| 1129 | * \returns the original type or a not allowed one */ |
| 1130 | typetype_t search_for_not_allowed_type(map<Type*, void>& type_chain, |
| 1131 | map<typetype_t, void>& not_allowed); |
| 1132 | /** Set the owner and its type type */ |
| 1133 | void set_ownertype(TypeOwner_t ot, Node *o) { ownertype = ot; owner = o; } |
| 1134 | |
| 1135 | bool is_untagged() const; |
| 1136 | |
| 1137 | inline boolean is_pard_type_instance() { return pard_type_instance; } |
| 1138 | inline void set_pard_type_instance() { pard_type_instance = true; } |
| 1139 | |
| 1140 | /** Calculates the type's display name from the genname (replaces double |
| 1141 | * underscore characters with single ones) */ |
| 1142 | string get_dispname() const; |
| 1143 | |
| 1144 | /** Generates the JSON schema segment that would validate this type and |
| 1145 | * inserts it into the main schema. |
| 1146 | * @param json JSON tokenizer containing the main JSON schema |
| 1147 | * @param embedded true if the type is embedded in another type's definition; |
| 1148 | * false if it has its own definition |
| 1149 | * @param as_value true if this type is a field of a union with the "as value" |
| 1150 | * coding instruction */ |
| 1151 | void generate_json_schema(JSON_Tokenizer& json, bool embedded, bool as_value); |
| 1152 | |
| 1153 | /** Generates the JSON schema segment that would validate a record of, set of |
| 1154 | * or array type and inserts it into the main schema. */ |
| 1155 | void generate_json_schema_array(JSON_Tokenizer& json); |
| 1156 | |
| 1157 | /** Generates the JSON schema segment that would validate a record or set type |
| 1158 | * and inserts it into the main schema. */ |
| 1159 | void generate_json_schema_record(JSON_Tokenizer& json); |
| 1160 | |
| 1161 | /** Generates the JSON schema segment that would validate a union type or |
| 1162 | * an anytype and inserts it into the main schema. */ |
| 1163 | void generate_json_schema_union(JSON_Tokenizer& json); |
| 1164 | |
| 1165 | /** Generates a reference to this type's schema segment and inserts it into |
| 1166 | * the given schema. */ |
| 1167 | void generate_json_schema_ref(JSON_Tokenizer& json); |
| 1168 | }; |
| 1169 | |
| 1170 | /** @} end of AST_Type group */ |
| 1171 | |
| 1172 | } // namespace Common |
| 1173 | |
| 1174 | #endif // _Common_Type_HH |