1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2015 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
9 #include "../Identifier.hh"
10 #include "../CompilerError.hh"
12 #include "TokenBuf.hh" // Ass_pard needs that
13 #include "../Value.hh"
16 #include "../CodeGenHelper.hh"
17 #include "../../common/JSON_Tokenizer.hh"
19 /* defined in asn1p.y */
20 extern int asn1_parse_string(const char* p_str
);
22 extern Common::Modules
*modules
; // in main.cc
26 Module
*Assignments::_spec_asss
=0;
27 Assignments
*parsed_assignments
;
29 // =================================
31 // =================================
34 for (size_t i
= 0; i
< syms_v
.size(); i
++) delete syms_v
[i
];
39 Symbols
* Symbols::clone() const
41 FATAL_ERROR("Asn::Symbols::clone()");
45 void Symbols::add_sym(Identifier
*p_id
)
48 FATAL_ERROR("NULL parameter: Asn::Symbols::add_sym()");
52 void Symbols::chk_uniq(const Location
& p_loc
)
54 for(size_t i
=0; i
<syms_v
.size(); i
++) {
55 Identifier
*id
= syms_v
[i
];
56 const string
& name
= id
->get_name();
57 if (syms_m
.has_key(name
)) {
58 p_loc
.error("Duplicate identifier in SymbolList: `%s'",
59 id
->get_dispname().c_str());
60 } else syms_m
.add(name
, id
);
64 // =================================
66 // =================================
68 Exports::Exports(bool p_expall
)
69 : Node(), Location(), checked(false), my_mod(0), expall(p_expall
),
70 symbols(expall
? 0 : new Symbols())
73 Exports::Exports(Symbols
*p_symlist
)
74 : Node(), Location(), checked(false), my_mod(0), expall(false),
75 symbols(p_symlist
? p_symlist
: new Symbols())
83 Exports
* Exports::clone() const
85 FATAL_ERROR("Asn::Exports::clone()");
89 bool Exports::exports_sym(const Identifier
& p_id
)
91 if(!checked
) chk_exp();
92 if (expall
) return true;
93 else return symbols
->syms_m
.has_key(p_id
.get_name());
96 void Exports::chk_exp()
100 Ref_defd_simple
*ref
=0;
101 Error_Context
cntxt(this, "In EXPORTS of module `%s'",
102 my_mod
->get_modid().get_dispname().c_str());
103 symbols
->chk_uniq(*this);
104 for(size_t i
=0; i
<symbols
->syms_m
.size(); i
++) {
105 ref
=new Ref_defd_simple(0, symbols
->syms_m
.get_nth_elem(i
)->clone());
106 /* check whether exists or not */
107 my_mod
->get_ass_bySRef(ref
);
113 // =================================
115 // =================================
117 ImpMod::ImpMod(Identifier
*p_modid
, Symbols
*p_symlist
)
118 : Node(), Location(), my_mod(0), modid(p_modid
), mod(0)
121 FATAL_ERROR("NULL parameter: Asn::ImpMod::ImpMod()");
122 set_fullname("<imports>."+modid
->get_dispname());
123 symbols
= p_symlist
? p_symlist
: new Symbols();
132 ImpMod
* ImpMod::clone() const
134 FATAL_ERROR("Asn::ImpMod::clone()");
138 bool ImpMod::has_sym(const Identifier
& p_id
) const
140 return symbols
->syms_m
.has_key(p_id
.get_name());
143 void ImpMod::chk_imp(ReferenceChain
& refch
)
146 FATAL_ERROR("Asn::ImpMod::chk_imp(): my_mod is NULL");
147 Common::Module
*m
=modules
->get_mod_byId(*modid
);
148 symbols
->chk_uniq(*this);
149 vector
<Common::Module
> modules
;
150 m
->chk_imp(refch
, modules
);
152 if(m
->get_gen_code()) my_mod
->set_gen_code();
153 for(size_t i
=0; i
<symbols
->syms_m
.size(); i
++) {
154 const Identifier
*id
=symbols
->syms_m
.get_nth_elem(i
);
155 Ref_defd_simple
ref(0, new Identifier(*id
));
156 ref
.set_location(*this);
158 if(!m
->get_ass_bySRef(&ref
)) err
=true;
159 if(!err
&& !m
->exports_sym(*id
)) {
160 error("Symbol `%s' is not exported from module `%s'",
161 id
->get_dispname().c_str(),
162 m
->get_modid().get_dispname().c_str());
163 /* to avoid more error messages do not set err to true */
167 symbols
->syms_m
.erase(symbols
->syms_m
.get_nth_key(i
));
168 // do not delete id; it is stored in the vector
174 void ImpMod::generate_code(output_struct
*target
)
176 const char *module_name
= modid
->get_name().c_str();
178 target
->header
.includes
= mputprintf(target
->header
.includes
,
179 "#include \"%s.hh\"\n",
180 duplicate_underscores
? module_name
: modid
->get_ttcnname().c_str());
182 target
->functions
.pre_init
= mputprintf(target
->functions
.pre_init
,
183 "%s%s.pre_init_module();\n", module_name
,
187 // =================================
189 // =================================
193 for(size_t i
=0; i
<impmods_v
.size(); i
++)
201 Imports
* Imports::clone() const
203 FATAL_ERROR("Asn::Imports::clone()");
207 void Imports::add_impmod(ImpMod
*p_impmod
)
210 FATAL_ERROR("NULL parameter: Asn::Imports::add_impmod(): my_mod is NULL");
211 impmods_v
.add(p_impmod
);
212 p_impmod
->set_my_mod(my_mod
);
215 void Imports::set_my_mod(Module
*p_mod
)
218 for(size_t i
=0; i
<impmods_v
.size(); i
++)
219 impmods_v
[i
]->set_my_mod(my_mod
);
222 void Imports::chk_imp(ReferenceChain
& refch
)
226 if (impmods_v
.size() <= 0) return;
228 if (!my_mod
) FATAL_ERROR("Asn::Imports::chk_imp()");
230 for (size_t n
= 0; n
< impmods_v
.size(); n
++) {
231 ImpMod
*im
= impmods_v
[n
];
232 const Identifier
& im_id
= im
->get_modid();
233 Error_Context
cntxt(this, "In IMPORTS FROM `%s'",
234 im_id
.get_dispname().c_str());
235 if (!modules
->has_mod_withId(im_id
)) {
236 im
->error("There is no module with identifier `%s'",
237 im_id
.get_dispname().c_str());
240 Common::Module
*m
= modules
->get_mod_byId(im_id
);
242 if (m
->get_moduletype() != Module::MOD_ASN
) {
243 im
->error("An ASN.1 module cannot import from a TTCN-3 module");
246 else if (m
== my_mod
) {
247 im
->error("A module cannot import from itself");
250 // check the imports recursively
254 // detect circular imports
255 if (!is_circular
&& m
->is_visible(my_mod
)) is_circular
= true;
256 const string
& im_name
= im_id
.get_name();
257 if (impmods
.has_key(im_name
)) {
258 const char *dispname_str
= im_id
.get_dispname().c_str();
259 im
->error("Duplicate import from module `%s'", dispname_str
);
260 impmods
[im_name
]->note("Previous import from `%s' is here",
262 } else impmods
.add(im_name
, im
);
263 Symbols
*syms
= im
->symbols
;
264 for (size_t i
=0; i
<syms
->syms_m
.size(); i
++) {
265 const Identifier
*id
= syms
->syms_m
.get_nth_elem(i
);
266 const string
& key
= id
->get_name();
267 if(impsyms_1
.has_key(key
)) {
268 if(impsyms_1
[key
]!=m
) {
269 impsyms_1
.erase(key
);
270 impsyms_m
.add(key
, 0);
273 else if(!impsyms_m
.has_key(key
)) {
274 impsyms_1
.add(key
, m
);
280 bool Imports::has_impsym_withId(const Identifier
& p_id
) const
282 if (!checked
) FATAL_ERROR("Imports::has_impsym_withId()");
283 const string
& name
= p_id
.get_name();
284 return impsyms_1
.has_key(name
) || impsyms_m
.has_key(name
);
287 void Imports::get_imported_mods(Module::module_set_t
& p_imported_mods
)
289 for (size_t i
= 0; i
< impmods_v
.size(); i
++) {
290 Common::Module
*m
= impmods_v
[i
]->get_mod();
292 if (!p_imported_mods
.has_key(m
)) {
293 p_imported_mods
.add(m
, 0);
294 m
->get_visible_mods(p_imported_mods
);
299 void Imports::generate_code(output_struct
*target
)
301 bool base_lib_needed
= true;
302 for (size_t i
= 0; i
< impmods_v
.size(); i
++) {
303 ImpMod
*im
= impmods_v
[i
];
304 Common::Module
*m
= im
->get_mod();
305 // do not include the header file of the base library if a real
306 // (not circular) imported module is found
307 if (base_lib_needed
&& !m
->is_visible(my_mod
)) base_lib_needed
= false;
308 // inclusion of m's header file can be eliminated if we find another
309 // imported module that imports m
310 bool covered
= false;
311 for (size_t j
= 0; j
< impmods_v
.size(); j
++) {
312 // skip over the same import definition
313 if (j
== i
) continue;
314 Common::Module
*m2
= impmods_v
[j
]->get_mod();
315 // a module that is equivalent to the current module due to
316 // circular imports cannot be used to cover anything
317 if (m2
->is_visible(my_mod
)) continue;
318 if (m2
->is_visible(m
) && !m
->is_visible(m2
)) {
319 // m2 covers m (i.e. m is visible from m2)
320 // and they are not in the same import loop
325 // do not generate the #include if a covering module is found
326 if (!covered
) im
->generate_code(target
);
328 if (base_lib_needed
) {
329 // if no real import was found the base library definitions has to be
331 target
->header
.includes
= mputstr(target
->header
.includes
,
332 "#include <TTCN3.hh>\n");
336 // =================================
338 // =================================
340 Module::Module(Identifier
*p_modid
, TagDefault::tagdef_t p_tagdef
,
341 bool p_extens_impl
, Exports
*p_exp
, Imports
*p_imp
,
343 : Common::Module(MOD_ASN
, p_modid
), tagdef(p_tagdef
),
344 extens_impl(p_extens_impl
), exp(p_exp
), imp(p_imp
), asss(p_asss
)
346 if (!p_exp
|| !p_imp
|| !p_asss
)
347 FATAL_ERROR("NULL parameter: Asn::Module::Module()");
348 if(!p_modid
->isvalid_asn_modref()
349 && p_modid
->get_dispname()!="<internal>")
350 error("`%s' is not a valid module identifier",
351 p_modid
->get_dispname().c_str());
352 asss
->set_parent_scope(this);
353 exp
->set_my_mod(this);
354 imp
->set_my_mod(this);
364 Module
*Module::clone() const
366 FATAL_ERROR("Asn::Module::clone");
370 Common::Assignment
*Module::importAssignment(
371 const Identifier
& p_source_modid
, const Identifier
& p_id
) const
373 (void)p_source_modid
;
374 if (asss
->has_local_ass_withId(p_id
)) {
375 return asss
->get_local_ass_byId(p_id
);
379 void Module::set_fullname(const string
& p_fullname
)
381 Common::Module::set_fullname(p_fullname
);
382 exp
->set_fullname(p_fullname
+".<exports>");
383 imp
->set_fullname(p_fullname
+".<imports>");
384 asss
->set_fullname(p_fullname
);
387 Common::Assignments
*Module::get_scope_asss()
392 bool Module::has_imported_ass_withId(const Identifier
& p_id
)
394 return imp
->has_impsym_withId(p_id
);
397 Common::Assignment
* Module::get_ass_bySRef(Ref_simple
*p_ref
)
399 const Identifier
*r_modid
= p_ref
->get_modid();
400 const Identifier
*r_id
= p_ref
->get_id();
402 // return NULL if the reference is erroneous
405 Common::Module
*r_mod
=0;
407 if(!r_modid
|| *r_modid
==*modid
) {
408 if(asss
->has_local_ass_withId(*r_id
))
409 return asss
->get_local_ass_byId(*r_id
);
411 p_ref
->error("There is no assignment with name `%s'"
412 " in module `%s'", r_id
->get_dispname().c_str(),
413 modid
->get_dispname().c_str());
416 if(imp
->impsyms_1
.has_key(r_id
->get_name()))
417 r_mod
=imp
->impsyms_1
[r_id
->get_name()];
418 else if(imp
->impsyms_m
.has_key(r_id
->get_name())) {
419 p_ref
->error("There are more imported symbols with name `%s'"
420 " in module `%s'", r_id
->get_dispname().c_str(),
421 modid
->get_dispname().c_str());
425 p_ref
->error("There is no assignment or imported symbol"
426 " with name `%s' in module `%s'",
427 r_id
->get_dispname().c_str(),
428 modid
->get_dispname().c_str());
433 if(!imp
->has_impmod_withId(*r_modid
)) {
434 p_ref
->error("There is no imported module with name `%s'",
435 r_modid
->get_dispname().c_str());
438 if(!imp
->get_impmod_byId(*r_modid
)->has_sym(*r_id
)) {
439 p_ref
->error("There is no symbol with name `%s'"
440 " imported from module `%s'",
441 r_id
->get_dispname().c_str(),
442 r_modid
->get_dispname().c_str());
445 r_mod
=modules
->get_mod_byId(*r_modid
);
447 Ref_defd_simple
t_ref(0, r_id
->clone());
448 return r_mod
->get_ass_bySRef(&t_ref
);
451 Assignments
*Module::get_asss()
456 bool Module::exports_sym(const Identifier
& p_id
)
458 return exp
->exports_sym(p_id
);
461 void Module::chk_imp(ReferenceChain
& refch
, vector
<Common::Module
>& /*moduleStack*/)
463 if (imp_checked
) return;
464 const string
& module_name
= modid
->get_dispname();
465 if (refch
.exists(module_name
)) {
466 // Do not warning for circular import in ASN.1 module. It is legal
467 // warning("Circular import chain is not recommended: %s",
468 // refch.get_dispstr(module_name).c_str());
471 refch
.add(module_name
);
472 Error_Context backup
;
473 Error_Context
cntxt(this, "In ASN.1 module `%s'", module_name
.c_str());
477 collect_visible_mods();
482 DEBUG(1, "Checking ASN.1 module `%s'", modid
->get_dispname().c_str());
483 Error_Context
cntxt(this, "In ASN.1 module `%s'",
484 modid
->get_dispname().c_str());
490 void Module::get_imported_mods(module_set_t
& p_imported_mods
)
492 imp
->get_imported_mods(p_imported_mods
);
495 bool Module::has_circular_import()
497 return imp
->get_is_circular();
500 void Module::generate_code_internal(CodeGenHelper
& cgh
) {
501 imp
->generate_code(cgh
.get_current_outputstruct());
502 asss
->generate_code(cgh
);
505 void Module::dump(unsigned level
) const
507 DEBUG(level
, "ASN.1 module: %s", modid
->get_dispname().c_str());
508 asss
->dump(level
+ 1);
511 void Module::add_ass(Assignment
*p_ass
)
513 asss
->add_ass(p_ass
);
516 void Module::generate_json_schema(JSON_Tokenizer
& json
, map
<Type
*, JSON_Tokenizer
>& json_refs
)
518 // add a new property for this module
519 json
.put_next_token(JSON_TOKEN_NAME
, modid
->get_ttcnname().c_str());
521 // add type definitions into an object
522 json
.put_next_token(JSON_TOKEN_OBJECT_START
);
524 // cycle through all type assignments, insert schema segments and references
526 for (size_t i
= 0; i
< asss
->get_nof_asss(); ++i
) {
527 Common::Assignment
* ass
= asss
->get_ass_byIndex(i
);
528 if (Common::Assignment::A_TYPE
== ass
->get_asstype()) {
529 Asn::Assignment
* asn_ass
= dynamic_cast<Asn::Assignment
*>(ass
);
530 // skip parameterized types and their instances
531 if (NULL
== asn_ass
|| NULL
== asn_ass
->get_ass_pard()) {
532 Type
* t
= ass
->get_Type();
533 if (!t
->is_pard_type_instance() && t
->has_encoding(Type::CT_JSON
)) {
534 // insert type's schema segment
535 t
->generate_json_schema(json
, false, false);
537 if (json_refs_for_all_types
&& !json_refs
.has_key(t
)) {
538 // create JSON schema reference for the type
539 JSON_Tokenizer
* json_ref
= new JSON_Tokenizer
;
540 json_refs
.add(t
, json_ref
);
541 t
->generate_json_schema_ref(*json_ref
);
548 // end of type definitions
549 json
.put_next_token(JSON_TOKEN_OBJECT_END
);
552 // =================================
554 // =================================
556 Assignments::Assignments(const Assignments
& p
)
557 : Common::Assignments(p
), checked(false)
559 for(size_t i
= 0; i
< p
.asss_v
.size(); i
++)
560 add_ass(p
.asss_v
[i
]->clone());
563 Assignments::~Assignments()
565 for (size_t i
= 0; i
< asss_v
.size(); i
++) delete asss_v
[i
];
570 Assignments
*Assignments::clone() const
572 return new Assignments(*this);
575 void Assignments::set_fullname(const string
& p_fullname
)
577 Common::Assignments::set_fullname(p_fullname
);
578 string
s(p_fullname
);
579 if (s
!= "@") s
+= '.';
580 for (size_t i
= 0; i
< asss_v
.size(); i
++) {
581 Assignment
*ass
= asss_v
[i
];
582 ass
->set_fullname(s
+ass
->get_id().get_dispname());
586 bool Assignments::has_local_ass_withId(const Identifier
& p_id
)
588 if (!checked
) chk_uniq();
589 if (asss_m
.has_key(p_id
.get_name())) return true;
590 Assignments
*spec_asss
= _spec_asss
->get_asss();
591 if (spec_asss
!= this) return spec_asss
->has_ass_withId(p_id
);
595 Assignment
* Assignments::get_local_ass_byId(const Identifier
& p_id
)
597 if (!checked
) chk_uniq();
598 const string
& name
= p_id
.get_name();
599 if (asss_m
.has_key(name
)) return asss_m
[name
];
600 Assignments
*spec_asss
= _spec_asss
->get_asss();
601 if (spec_asss
!= this) return spec_asss
->get_local_ass_byId(p_id
);
605 size_t Assignments::get_nof_asss()
607 if (!checked
) chk_uniq();
608 return asss_m
.size();
611 Common::Assignment
* Assignments::get_ass_byIndex(size_t p_i
)
613 if (!checked
) chk_uniq();
614 return asss_m
.get_nth_elem(p_i
);
617 void Assignments::add_ass(Assignment
*p_ass
)
619 if (!p_ass
) FATAL_ERROR("Asn::Assignments::add_ass()");
621 p_ass
->set_my_scope(this);
623 const Identifier
& id
= p_ass
->get_id();
624 const string
& name
= id
.get_name();
625 if(asss_m
.has_key(name
)) {
626 const char *dispname_str
= id
.get_dispname().c_str();
627 p_ass
->error("Duplicate assignment with identifier `%s'", dispname_str
);
628 asss_m
[name
]->note("Previous assignment with identifier `%s' is here",
630 } else asss_m
.add(name
, p_ass
);
634 void Assignments::chk()
636 for(size_t i
= 0; i
< asss_v
.size(); i
++) asss_v
[i
]->chk();
639 void Assignments::chk_uniq()
643 Assignments
*spec_asss
= _spec_asss
->get_asss();
644 for(size_t i
= 0; i
< asss_v
.size(); i
++) {
645 Assignment
*ass
= asss_v
[i
];
646 const Identifier
& id
= ass
->get_id();
647 const string
& name
= id
.get_name();
648 if (this != spec_asss
&& spec_asss
->has_ass_withId(id
)) {
649 ass
->error("`%s' is a reserved identifier", id
.get_dispname().c_str());
650 } else if (asss_m
.has_key(name
)) {
651 const char *dispname_str
= id
.get_dispname().c_str();
652 ass
->error("Duplicate assignment with identifier `%s'", dispname_str
);
653 asss_m
[name
]->note("Previous assignment with identifier `%s' is here",
655 } else asss_m
.add(name
, ass
);
660 void Assignments::set_right_scope(Scope
*p_scope
)
662 for(size_t i
= 0; i
< asss_v
.size(); i
++)
663 asss_v
[i
]->set_right_scope(p_scope
);
666 void Assignments::create_spec_asss()
669 FATAL_ERROR("Assignments::create_spec_asss(): duplicate initialization");
671 const char *s_asss
= "$#&&&(#TITAN$#&&^#% Assignments\n"
672 "$#&&&(#TITAN$#&&^#% UpperIdentifier\"EXTERNAL\""
673 " ::= [UNIVERSAL 8] IMPLICIT SEQUENCE {\n"
674 " identification CHOICE {\n"
675 " syntaxes SEQUENCE {\n"
676 " abstract OBJECT IDENTIFIER,\n"
677 " transfer OBJECT IDENTIFIER\n"
679 " syntax OBJECT IDENTIFIER,\n"
680 " presentation-context-id INTEGER,\n"
681 " context-negotiation SEQUENCE {\n"
682 " presentation-context-id INTEGER,\n"
683 " transfer-syntax OBJECT IDENTIFIER\n"
685 " transfer-syntax OBJECT IDENTIFIER,\n"
688 " data-value-descriptor ObjectDescriptor OPTIONAL,\n"
689 " data-value OCTET STRING\n"
690 "} (WITH COMPONENTS {\n"
692 " identification (WITH COMPONENTS {\n"
694 " syntaxes ABSENT,\n"
695 " transfer-syntax ABSENT,\n"
700 "$#&&&(#TITAN$#&&^#% UpperIdentifier\"EMBEDDED PDV\""
701 " ::= [UNIVERSAL 11] IMPLICIT SEQUENCE {\n"
702 " identification CHOICE {\n"
703 " syntaxes SEQUENCE {\n"
704 " abstract OBJECT IDENTIFIER,\n"
705 " transfer OBJECT IDENTIFIER\n"
707 " syntax OBJECT IDENTIFIER,\n"
708 " presentation-context-id INTEGER,\n"
709 " context-negotiation SEQUENCE {\n"
710 " presentation-context-id INTEGER,\n"
711 " transfer-syntax OBJECT IDENTIFIER\n"
713 " transfer-syntax OBJECT IDENTIFIER,\n"
716 " data-value-descriptor ObjectDescriptor OPTIONAL,\n"
717 " data-value OCTET STRING\n"
718 "} (WITH COMPONENTS {\n"
720 " data-value-descriptor ABSENT\n"
723 "$#&&&(#TITAN$#&&^#% UpperIdentifier\"CHARACTER STRING\""
724 " ::= [UNIVERSAL 29] IMPLICIT SEQUENCE {\n"
725 " identification CHOICE {\n"
726 " syntaxes SEQUENCE {\n"
727 " abstract OBJECT IDENTIFIER,\n"
728 " transfer OBJECT IDENTIFIER\n"
730 " syntax OBJECT IDENTIFIER,\n"
731 " presentation-context-id INTEGER,\n"
732 " context-negotiation SEQUENCE {\n"
733 " presentation-context-id INTEGER,\n"
734 " transfer-syntax OBJECT IDENTIFIER\n"
736 " transfer-syntax OBJECT IDENTIFIER,\n"
739 " data-value-descriptor ObjectDescriptor OPTIONAL,\n"
740 " string-value OCTET STRING\n"
741 "} (WITH COMPONENTS {\n"
743 " data-value-descriptor ABSENT\n"
746 "$#&&&(#TITAN$#&&^#% UpperIdentifier\"REAL\""
747 " ::= [UNIVERSAL 9] IMPLICIT SEQUENCE {\n"
748 " mantissa INTEGER,\n"
749 " base INTEGER (2|10),\n"
750 " exponent INTEGER\n"
753 "$#&&&(#TITAN$#&&^#% UpperIdentifier\"TYPE-IDENTIFIER\"\n"
756 " &id OBJECT IDENTIFIER UNIQUE,\n"
760 " &Type IDENTIFIED BY &id\n"
763 "$#&&&(#TITAN$#&&^#% UpperIdentifier\"ABSTRACT-SYNTAX\""
765 " &id OBJECT IDENTIFIER UNIQUE,\n"
767 " &property BIT STRING {handles-invalid-encodings(0)} DEFAULT {}\n"
770 " &Type IDENTIFIED BY &id [HAS PROPERTY &property]\n"
774 if(asn1_parse_string(s_asss
) || !parsed_assignments
)
775 FATAL_ERROR("special assignments");
776 _spec_asss
=new Module
777 (new Identifier(Identifier::ID_ASN
, string("<internal>")),
778 TagDefault::AUTOMATIC
, false, new Exports(true), new Imports(),
780 _spec_asss
->set_location("<internal>");
781 _spec_asss
->set_scope_name(_spec_asss
->get_modid().get_dispname());
783 parsed_assignments
->set_fullname(string('@'));
787 // this is used to generate the files which are then
788 // included/copied/edited in core library
789 _spec_asss->set_gen_code();
790 _spec_asss->generate_code();
794 void Assignments::destroy_spec_asss()
797 FATAL_ERROR("Assignments::destroy_spec_asss(): duplicate cleanup");
803 bool Assignments::is_spec_asss(Common::Module
*p_mod
)
805 if (!p_mod
) FATAL_ERROR("Assignments::is_spec_asss()");
806 if (_spec_asss
) return p_mod
== static_cast<Common::Module
*>(_spec_asss
);
810 void Assignments::generate_code(output_struct
* target
)
812 for (size_t i
= 0; i
< asss_v
.size(); i
++) {
813 Assignment
*ass
= asss_v
[i
];
814 if (!top_level_pdu
|| ass
->get_checked()) ass
->generate_code(target
);
818 void Assignments::generate_code(CodeGenHelper
& cgh
) {
819 for (size_t i
= 0; i
< asss_v
.size(); i
++) {
820 Assignment
*ass
= asss_v
[i
];
821 if (!top_level_pdu
|| ass
->get_checked()) ass
->generate_code(cgh
);
825 void Assignments::dump(unsigned level
) const
827 DEBUG(level
, "Assignments (%lu pcs.)", (unsigned long) asss_v
.size());
828 for(size_t i
= 0; i
< asss_v
.size(); i
++) asss_v
[i
]->dump(level
+ 1);
831 // =================================
833 // =================================
835 Ass_pard::Ass_pard(Block
*p_parlist_block
)
836 : Common::Node(), parlist_block(p_parlist_block
)
839 FATAL_ERROR("NULL parameter: Asn::Ass_pard::Ass_pard()");
842 Ass_pard::Ass_pard(const Ass_pard
& p
)
845 parlist_block
=p
.parlist_block
?p
.parlist_block
->clone():0;
846 for(size_t i
=0; i
<p
.dummyrefs
.size(); i
++)
847 dummyrefs
.add(p
.dummyrefs
[i
]->clone());
848 for(size_t i
=0; i
<p
.governors
.size(); i
++)
849 governors
.add(p
.governors
[i
]->clone());
852 Ass_pard::~Ass_pard()
854 delete parlist_block
;
855 for (size_t i
= 0; i
< dummyrefs
.size(); i
++) delete dummyrefs
[i
];
857 for (size_t i
= 0; i
< governors
.size(); i
++) delete governors
[i
];
859 for (size_t i
= 0; i
< inst_cnts
.size(); i
++)
860 delete inst_cnts
.get_nth_elem(i
);
864 void Ass_pard::preparse_pars()
866 if(!parlist_block
) return;
868 (my_ass
, "While checking formal parameters of parameterized"
869 " assignment `%s'", my_ass
->get_fullname().c_str());
870 TokenBuf
*parlist_tb
=parlist_block
->get_TokenBuf();
871 enum state_type
{S_START
, S_GOV
, S_DUMMYREF
, S_COMMA
, S_RDY
, S_ERR
};
873 for(state_type st
=S_START
; st
!=S_RDY
; ) {
876 gov_tb
=new TokenBuf();
877 switch(parlist_tb
->get_at(1)->get_token()) {
887 Token
*token
=parlist_tb
->pop_front_token();
888 switch(token
->get_token()) {
891 token
->error("Syntax error, premature end of parameter"
901 gov_tb
->push_back_token(token
);
905 Token
*token
=parlist_tb
->pop_front_token();
906 switch(token
->get_token()) {
907 case TOK_UpperIdentifier
:
908 case TOK_LowerIdentifier
:
909 dummyrefs
.add(token
->get_semval_id().clone());
910 gov_tb
->push_front_token(token
);
911 gov_tb
->push_back_kw_token(TOK_Assignment
);
912 governors
.add(gov_tb
);
919 token
->error("Syntax error, DummyReference was expected");
923 break;} // S_DUMMYREF
925 Token
*token
=parlist_tb
->pop_front_token();
926 switch(token
->get_token()) {
934 token
->error("Syntax error, `,' was expected");
941 for (size_t i
= 0; i
< dummyrefs
.size(); i
++) delete dummyrefs
[i
];
943 for (size_t i
= 0; i
< governors
.size(); i
++) delete governors
[i
];
949 FATAL_ERROR("Ass_pard::preparse_pars()");
952 delete parlist_block
;
956 size_t Ass_pard::get_nof_pars()
958 if (parlist_block
) preparse_pars();
959 return dummyrefs
.size();
962 const Identifier
& Ass_pard::get_nth_dummyref(size_t i
)
964 if (parlist_block
) preparse_pars();
965 return *(dummyrefs
[i
]);
968 TokenBuf
* Ass_pard::clone_nth_governor(size_t i
)
970 if (parlist_block
) preparse_pars();
971 return governors
[i
]->clone();
974 size_t Ass_pard::new_instnum(Common::Module
*p_mod
)
976 if (!p_mod
) FATAL_ERROR("Ass_pard::new_instnum()");
977 if (inst_cnts
.has_key(p_mod
)) return ++(*inst_cnts
[p_mod
]);
979 inst_cnts
.add(p_mod
, new size_t(1));
984 // =================================
986 // =================================
988 Assignment::Assignment(const Assignment
& p
)
989 : Common::Assignment(p
), dontgen(false)
992 ass_pard
=p
.ass_pard
->clone();
993 ass_pard
->set_my_ass(this);
998 string
Assignment::get_genname() const
1001 my_scope
->get_parent_scope() == my_scope
->get_scope_mod()) {
1002 // use the simple identifier if the assignment does not have scope
1003 // or it is a simple assignment at module scope
1004 return id
->get_name();
1006 // this assignment belongs to an instantiation of a parameterized
1007 // assignment: use the name of the parent scope to obtain genname
1008 string
genname_asn("@");
1009 genname_asn
+= my_scope
->get_scope_name();
1010 const string
& id_dispname
= id
->get_dispname();
1011 bool is_parass
= id_dispname
.find('.') == id_dispname
.size();
1013 // the assignment has a normal identifier:
1014 // it represents a formal parameter -> actual parameter binding
1015 // the id (which is the dummy reference) must be used to get a
1018 genname_asn
+= id_dispname
;
1020 // otherwise the assignment represents an instance of the parameterized
1021 // assignment itself: the scope name can be used alone as genname
1022 string
ret_val(Identifier::asn_2_name(genname_asn
));
1023 // in case of parameter assignments a suffix is appended to avoid name
1024 // clash with the embedded settings of the same instantiation
1025 if (is_parass
) ret_val
+= "_par_";
1030 Assignment
* Assignment::new_instance0()
1032 // Classes derived from Assignment must implement new_instance0.
1033 // See Asn::Ass_*::new_instance0
1034 FATAL_ERROR("Asn::Assignment::new_instance0()");
1038 Assignment::Assignment(asstype_t p_asstype
, Identifier
*p_id
,
1039 Ass_pard
*p_ass_pard
)
1040 : Common::Assignment(p_asstype
, p_id
),
1041 ass_pard(p_ass_pard
), dontgen(false)
1043 if(ass_pard
) ass_pard
->set_my_ass(this);
1046 Assignment::~Assignment()
1051 bool Assignment::is_asstype(asstype_t p_asstype
, ReferenceChain
* refch
)
1053 bool destroy_refch
=false;
1055 refch
=new ReferenceChain(this, "While examining kind of assignment");
1057 } else refch
->mark_state();
1058 bool b
=(p_asstype
==asstype
);
1059 if(!refch
->add(get_fullname())) b
=p_asstype
==A_ERROR
;
1060 if(destroy_refch
) delete refch
;
1061 else refch
->prev_state();
1065 Assignment
* Assignment::new_instance(Common::Module
*p_mod
)
1068 error("`%s' is not a parameterized assignment",
1069 get_fullname().c_str());
1072 Assignment
*new_ass
=new_instance0();
1073 delete new_ass
->id
; // it was just a temporary, containing "<error>"
1074 string
new_name(id
->get_asnname());
1076 new_name
+= p_mod
->get_modid().get_asnname();
1077 new_name
+= ".inst";
1078 new_name
+= Int2string(ass_pard
->new_instnum(p_mod
));
1079 new_ass
->id
=new Identifier(Identifier::ID_ASN
, new_name
);
1083 Type
* Assignment::get_Type()
1085 error("`%s' is not a type assignment", get_fullname().c_str());
1089 Value
* Assignment::get_Value()
1091 error("`%s' is not a value assignment", get_fullname().c_str());
1095 ValueSet
* Assignment::get_ValueSet()
1097 error("`%s' is not a valueset assignment", get_fullname().c_str());
1101 ObjectClass
* Assignment::get_ObjectClass()
1103 error("`%s' is not a objectclass assignment", get_fullname().c_str());
1107 Object
* Assignment::get_Object()
1109 error("`%s' is not a object assignment", get_fullname().c_str());
1113 ObjectSet
* Assignment::get_ObjectSet()
1115 error("`%s' is not a objectset assignment", get_fullname().c_str());
1119 void Assignment::chk()
1122 ass_pard
->get_nof_pars();
1126 DEBUG(7, "`%s' assignment not checked.", get_fullname().c_str());
1129 void Assignment::dump(unsigned level
) const
1131 DEBUG(level
, "Assignment(%d): %s%s", get_asstype(),
1132 id
->get_dispname().c_str(), ass_pard
?"{}":"");
1135 // =================================
1137 // =================================
1139 Ass_Undef::Ass_Undef(Identifier
*p_id
, Ass_pard
*p_ass_pard
,
1140 Node
*p_left
, Node
*p_right
)
1141 : Assignment(A_UNDEF
, p_id
, p_ass_pard
),
1142 left(p_left
), right(p_right
), right_scope(0), ass(0)
1145 FATAL_ERROR("NULL parameter: Asn::Ass_Undef::Ass_Undef()");
1148 Ass_Undef::Ass_Undef(const Ass_Undef
& p
)
1149 : Assignment(p
), right_scope(0)
1151 left
=p
.left
?p
.left
->clone():0;
1152 right
=p
.right
?p
.right
->clone():0;
1153 ass
=p
.ass
?p
.ass
->clone():0;
1156 Ass_Undef::~Ass_Undef()
1163 Assignment
* Ass_Undef::clone() const
1165 if(ass
) return ass
->clone();
1166 else return new Ass_Undef(*this);
1169 Assignment
* Ass_Undef::new_instance0()
1171 if(ass
) FATAL_ERROR("Asn::Ass_Undef::new_instance0()");
1172 return new Ass_Undef
1173 (new Identifier(Identifier::ID_ASN
, string("<error>")),
1174 0, left
?left
->clone():0, right
->clone());
1177 Assignment::asstype_t
Ass_Undef::get_asstype() const
1179 const_cast<Ass_Undef
*>(this)->classify_ass();
1183 void Ass_Undef::set_fullname(const string
& p_fullname
)
1185 Assignment::set_fullname(p_fullname
);
1186 if (left
) left
->set_fullname(p_fullname
);
1187 if (right
) right
->set_fullname(p_fullname
);
1188 if (ass
) ass
->set_fullname(p_fullname
);
1191 void Ass_Undef::set_my_scope(Scope
*p_scope
)
1193 Assignment::set_my_scope(p_scope
);
1194 if(ass
) ass
->set_my_scope(p_scope
);
1195 right_scope
=p_scope
;
1198 void Ass_Undef::set_right_scope(Scope
*p_scope
)
1200 if(ass
) ass
->set_right_scope(p_scope
);
1201 right_scope
=p_scope
;
1204 bool Ass_Undef::is_asstype(asstype_t p_asstype
, ReferenceChain
* refch
)
1206 classify_ass(refch
);
1207 return asstype
!= A_ERROR
? ass
->is_asstype(p_asstype
, refch
) : false;
1210 Ass_pard
* Ass_Undef::get_ass_pard() const
1213 return ass
->get_ass_pard();
1218 bool Ass_Undef::_error_if_pard()
1221 error("`%s' is a parameterized assignment", get_fullname().c_str());
1227 Setting
* Ass_Undef::get_Setting()
1229 if(_error_if_pard()) return 0;
1231 return ass
->get_Setting();
1234 Type
* Ass_Undef::get_Type()
1236 if(_error_if_pard()) return 0;
1238 return ass
->get_Type();
1241 Value
* Ass_Undef::get_Value()
1243 if(_error_if_pard()) return 0;
1245 return ass
->get_Value();
1248 ValueSet
* Ass_Undef::get_ValueSet()
1250 if(_error_if_pard()) return 0;
1252 return ass
->get_ValueSet();
1255 ObjectClass
* Ass_Undef::get_ObjectClass()
1257 if(_error_if_pard()) return 0;
1259 return ass
->get_ObjectClass();
1262 Object
* Ass_Undef::get_Object()
1264 if(_error_if_pard()) return 0;
1266 return ass
->get_Object();
1269 ObjectSet
* Ass_Undef::get_ObjectSet()
1271 if(_error_if_pard()) return 0;
1273 return ass
->get_ObjectSet();
1276 void Ass_Undef::chk()
1280 ass_pard
->get_nof_pars();
1289 void Ass_Undef::generate_code(output_struct
*target
, bool)
1291 if (ass_pard
|| dontgen
) return;
1293 ass
->generate_code(target
);
1296 void Ass_Undef::generate_code(CodeGenHelper
& cgh
) {
1297 if (ass_pard
|| dontgen
) return;
1299 ass
->generate_code(cgh
);
1302 void Ass_Undef::dump(unsigned level
) const
1307 DEBUG(level
, "Undef assignment: %s%s",
1308 id
->get_dispname().c_str(), ass_pard
?"{}":"");
1312 void Ass_Undef::classify_ass(ReferenceChain
*refch
)
1314 if(asstype
!=A_UNDEF
) return;
1315 bool destroy_refch
=false;
1317 refch
=new ReferenceChain(this, "While examining kind of assignment");
1319 } else refch
->mark_state();
1321 Error_Context
ec_backup(1);
1322 Error_Context
cntxt(this, "In assignment `%s'",
1323 id
->get_dispname().c_str());
1325 /* temporary pointers */
1327 Reference
*t_ref2
=0;
1330 if(!refch
->add(get_fullname()))
1332 if((t_ref
=dynamic_cast<Reference
*>(left
))) {
1333 t_ref
->set_my_scope(my_scope
);
1334 if(t_ref
->refers_to_st(Setting::S_ERROR
, refch
))
1337 if((t_ref
=dynamic_cast<Reference
*>(right
))) {
1338 t_ref
->set_my_scope(right_scope
);
1340 if(t_ref->refers_to_st(Setting::S_ERROR, refch))
1341 t_ref->error("Cannot recognize assignment `%s'",
1342 t_ref->get_dispname().c_str());
1346 if(id
->isvalid_asn_objclassref()
1348 && (t_ref
=dynamic_cast<Ref_defd
*>(right
))
1349 && t_ref
->refers_to_st(Setting::S_OC
, refch
)
1351 ass
=new Ass_OC(id
->clone(), ass_pard
, new OC_refd(t_ref
));
1356 else if(id
->isvalid_asn_typeref()
1358 && (t_ref
=dynamic_cast<Ref_defd
*>(right
))
1359 && (t_ref
->refers_to_st(Setting::S_T
, refch
)
1360 || t_ref
->refers_to_st(Setting::S_VS
, refch
))
1362 Type
*t_type
=new Type(Type::T_REFD
, t_ref
);
1363 t_type
->set_location(*t_ref
);
1364 ass
=new Ass_T(id
->clone(), ass_pard
, t_type
);
1369 else if(id
->isvalid_asn_objsetref()
1370 && (t_ref
=dynamic_cast<Ref_simple
*>(left
))
1371 && (t_block
=dynamic_cast<Block
*>(right
))
1372 && t_ref
->refers_to_st(Setting::S_OC
, refch
)
1374 ass
=new Ass_OS(id
->clone(), ass_pard
,
1375 new OC_refd(t_ref
), new OS_defn(t_block
));
1381 else if(id
->isvalid_asn_valsetref()
1382 && (t_ref
=dynamic_cast<Ref_simple
*>(left
))
1383 && (t_block
=dynamic_cast<Block
*>(right
))
1384 && (t_ref
->refers_to_st(Setting::S_T
, refch
)
1385 || t_ref
->refers_to_st(Setting::S_VS
, refch
))
1387 Type
*t_type
=new Type(Type::T_REFD
, t_ref
);
1388 t_type
->set_location(*t_ref
);
1389 ass
=new Ass_VS(id
->clone(), ass_pard
, t_type
, t_block
);
1395 else if(id
->isvalid_asn_objref()
1396 && (t_ref
=dynamic_cast<Ref_simple
*>(left
))
1397 && ((t_block
=dynamic_cast<Block
*>(right
))
1398 || (t_ref2
=dynamic_cast<Reference
*>(right
)))
1399 && t_ref
->refers_to_st(Setting::S_OC
, refch
)
1401 OC_refd
*t_oc
=new OC_refd(t_ref
);
1402 t_oc
->set_location(*t_ref
);
1404 Obj_defn
*t_obj
=new Obj_defn(t_block
);
1405 t_obj
->set_location(*t_block
);
1406 ass
=new Ass_O(id
->clone(), ass_pard
, t_oc
, t_obj
);
1409 Obj_refd
*t_obj
=new Obj_refd(t_ref2
);
1410 t_obj
->set_location(*t_ref2
);
1411 ass
=new Ass_O(id
->clone(), ass_pard
, t_oc
, t_obj
);
1418 else if(id
->isvalid_asn_valref()
1419 && (t_ref
=dynamic_cast<Ref_simple
*>(left
))
1420 && ((t_block
=dynamic_cast<Block
*>(right
))
1421 || (t_ref2
=dynamic_cast<Reference
*>(right
)))
1422 && (t_ref
->refers_to_st(Setting::S_T
, refch
)
1423 || t_ref
->refers_to_st(Setting::S_VS
, refch
))
1425 Type
*t_type
=new Type(Type::T_REFD
, t_ref
);
1426 t_type
->set_location(*t_ref
);
1428 Value
*t_value
=new Value(Value::V_UNDEF_BLOCK
, t_block
);
1429 t_value
->set_location(*t_block
);
1430 ass
=new Ass_V(id
->clone(), ass_pard
, t_type
, t_value
);
1433 Ref_defd_simple
*t_ref3
=dynamic_cast<Ref_defd_simple
*>(t_ref2
);
1434 if(t_ref3
&& !t_ref3
->get_modid()) {
1435 Value
*t_val
=new Value(Value::V_UNDEF_LOWERID
,
1436 t_ref3
->get_id()->clone());
1437 t_val
->set_location(*t_ref3
);
1438 ass
=new Ass_V(id
->clone(), ass_pard
, t_type
, t_val
);
1442 Value
*t_val
=new Value(Value::V_REFD
, t_ref2
);
1443 t_val
->set_location(*t_ref2
);
1444 ass
=new Ass_V(id
->clone(), ass_pard
, t_type
, t_val
);
1457 error("Cannot recognize assignment");
1458 ass
= new Ass_Error(id
->clone(), ass_pard
);
1461 ass
->set_location(*this);
1462 ass
->set_my_scope(my_scope
);
1463 ass
->set_right_scope(right_scope
);
1464 ass
->set_fullname(get_fullname());
1465 if(destroy_refch
) delete refch
;
1466 else refch
->prev_state();
1469 // =================================
1471 // =================================
1473 Ass_Error::Ass_Error(Identifier
*p_id
, Ass_pard
*p_ass_pard
)
1474 : Assignment(A_ERROR
, p_id
, p_ass_pard
),
1475 setting_error(0), type_error(0), value_error(0)
1479 Ass_Error::~Ass_Error()
1481 delete setting_error
;
1486 Assignment
* Ass_Error::clone() const
1488 return new Ass_Error(id
->clone(), ass_pard
);
1491 Assignment
* Ass_Error::new_instance0()
1493 return new Ass_Error
1494 (new Identifier(Identifier::ID_ASN
, string("<error>")), 0);
1497 bool Ass_Error::is_asstype(asstype_t p_asstype
, ReferenceChain
*)
1499 return p_asstype
==A_ERROR
;
1502 Setting
* Ass_Error::get_Setting()
1505 setting_error
= new Common::Setting_Error();
1506 return setting_error
;
1509 Type
* Ass_Error::get_Type()
1512 type_error
= new Type(Type::T_ERROR
);
1516 Value
* Ass_Error::get_Value()
1519 value_error
= new Value(Value::V_ERROR
);
1523 ValueSet
* Ass_Error::get_ValueSet()
1525 FATAL_ERROR("Ass_Error::get_ValueSet()");
1529 ObjectClass
* Ass_Error::get_ObjectClass()
1531 FATAL_ERROR("Ass_Error::get_ObjectClass()");
1535 Object
* Ass_Error::get_Object()
1537 FATAL_ERROR("Ass_Error::get_Object()");
1541 ObjectSet
* Ass_Error::get_ObjectSet()
1543 FATAL_ERROR("Ass_Error::get_ObjectSet()");
1547 void Ass_Error::chk()
1552 void Ass_Error::dump(unsigned level
) const
1554 DEBUG(level
, "Erroneous assignment: %s%s",
1555 id
->get_dispname().c_str(), ass_pard
?"{}":"");
1558 // =================================
1560 // =================================
1562 Ass_T::Ass_T(Identifier
*p_id
, Ass_pard
*p_ass_pard
, Type
*p_right
)
1563 : Assignment(A_TYPE
, p_id
, p_ass_pard
)
1566 FATAL_ERROR("NULL parameter: Asn::Ass_T::Ass_T()");
1567 p_right
->set_ownertype(Type::OT_TYPE_ASS
, this);
1571 Ass_T::Ass_T(const Ass_T
& p
)
1574 right
=p
.right
->clone();
1582 Assignment
* Ass_T::new_instance0()
1585 (new Identifier(Identifier::ID_ASN
, string("<error>")), 0, right
->clone());
1588 void Ass_T::set_fullname(const string
& p_fullname
)
1590 Assignment::set_fullname(p_fullname
);
1591 right
->set_fullname(p_fullname
);
1594 void Ass_T::set_my_scope(Scope
*p_scope
)
1596 Assignment::set_my_scope(p_scope
);
1597 right
->set_my_scope(p_scope
);
1600 void Ass_T::set_right_scope(Scope
*p_scope
)
1602 right
->set_my_scope(p_scope
);
1605 Type
* Ass_T::get_Type()
1608 error("`%s' is a parameterized type assignment",
1609 get_fullname().c_str());
1618 if (checked
) return;
1620 Error_Context
cntxt(this, "In type assignment `%s'",
1621 id
->get_dispname().c_str());
1623 ass_pard
->get_nof_pars();
1627 right
->set_genname(get_genname());
1629 ReferenceChain
refch(right
, "While checking embedded recursions");
1630 right
->chk_recursions(refch
);
1633 void Ass_T::generate_code(output_struct
*target
, bool)
1635 right
->generate_code(target
);
1638 void Ass_T::generate_code(CodeGenHelper
& cgh
) {
1639 if (ass_pard
|| dontgen
) return;
1640 generate_code(cgh
.get_outputstruct(right
));
1641 cgh
.finalize_generation(right
);
1644 void Ass_T::dump(unsigned level
) const
1646 DEBUG(level
, "Type assignment: %s%s",
1647 id
->get_dispname().c_str(), ass_pard
?"{}":"");
1654 // =================================
1656 // =================================
1658 Ass_V::Ass_V(Identifier
*p_id
, Ass_pard
*p_ass_pard
,
1659 Type
*p_left
, Value
*p_right
)
1660 : Assignment(A_CONST
, p_id
, p_ass_pard
)
1662 if(!p_left
|| !p_right
)
1663 FATAL_ERROR("NULL parameter: Asn::Ass_V::Ass_V()");
1665 left
->set_ownertype(Type::OT_VAR_ASS
, this);
1669 Ass_V::Ass_V(const Ass_V
& p
)
1672 left
=p
.left
->clone();
1673 right
=p
.right
->clone();
1682 Assignment
* Ass_V::new_instance0()
1685 (new Identifier(Identifier::ID_ASN
, string("<error>")), 0,
1686 left
->clone(), right
->clone());
1689 void Ass_V::set_fullname(const string
& p_fullname
)
1691 Assignment::set_fullname(p_fullname
);
1692 left
->set_fullname(p_fullname
+ ".<type>");
1693 right
->set_fullname(p_fullname
);
1696 void Ass_V::set_my_scope(Scope
*p_scope
)
1698 Assignment::set_my_scope(p_scope
);
1699 left
->set_my_scope(p_scope
);
1700 right
->set_my_scope(p_scope
);
1703 void Ass_V::set_right_scope(Scope
*p_scope
)
1705 right
->set_my_scope(p_scope
);
1709 Type
* Ass_V::get_Type()
1715 Value
* Ass_V::get_Value()
1718 error("`%s' is a parameterized value assignment",
1719 get_fullname().c_str());
1729 Error_Context
cntxt(this, "In value assignment `%s'",
1730 id
->get_dispname().c_str());
1732 ass_pard
->get_nof_pars();
1737 static const string
_T_("_T_");
1738 left
->set_genname(_T_
, get_genname());
1740 right
->set_my_governor(left
);
1741 left
->chk_this_value_ref(right
);
1743 left
->chk_this_value(right
, 0, Type::EXPECTED_CONSTANT
, INCOMPLETE_NOT_ALLOWED
,
1744 OMIT_NOT_ALLOWED
, SUB_CHK
, IMPLICIT_OMIT
);
1746 ReferenceChain
refch(right
, "While checking embedded recursions");
1747 right
->chk_recursions(refch
);
1749 if (!semantic_check_only
) {
1750 right
->set_genname_prefix("const_");
1751 right
->set_genname_recursive(get_genname());
1752 right
->set_code_section(GovernedSimple::CS_PRE_INIT
);
1756 void Ass_V::generate_code(output_struct
*target
, bool)
1758 if (ass_pard
|| dontgen
) return;
1759 left
->generate_code(target
);
1761 Code::init_cdef(&cdef
);
1762 left
->generate_code_object(&cdef
, right
);
1763 cdef
.init
= right
->generate_code_init(cdef
.init
,
1764 right
->get_lhs_name().c_str());
1765 Code::merge_cdef(target
, &cdef
);
1766 Code::free_cdef(&cdef
);
1769 void Ass_V::generate_code(CodeGenHelper
& cgh
) {
1770 generate_code(cgh
.get_current_outputstruct());
1773 void Ass_V::dump(unsigned level
) const
1775 DEBUG(level
, "Value assignment: %s%s",
1776 id
->get_dispname().c_str(), ass_pard
?"{}":"");
1783 // =================================
1785 // =================================
1787 Ass_VS::Ass_VS(Identifier
*p_id
, Ass_pard
*p_ass_pard
,
1788 Type
*p_left
, Block
*p_right
)
1789 : Assignment(A_VS
, p_id
, p_ass_pard
), right_scope(0)
1791 if(!p_left
|| !p_right
)
1792 FATAL_ERROR("NULL parameter: Asn::Ass_VS::Ass_VS()");
1794 left
->set_ownertype(Type::OT_VSET_ASS
, this);
1798 Ass_VS::Ass_VS(const Ass_VS
& p
)
1799 : Assignment(p
), right_scope(0)
1801 left
=p
.left
->clone();
1802 right
=p
.right
->clone();
1811 Assignment
* Ass_VS::new_instance0()
1814 (new Identifier(Identifier::ID_ASN
, string("<error>")), 0,
1815 left
->clone(), right
->clone());
1818 void Ass_VS::set_fullname(const string
& p_fullname
)
1820 Assignment::set_fullname(p_fullname
);
1821 left
->set_fullname(p_fullname
);
1822 right
->set_fullname(p_fullname
);
1825 void Ass_VS::set_my_scope(Scope
*p_scope
)
1827 Assignment::set_my_scope(p_scope
);
1828 left
->set_my_scope(p_scope
);
1831 void Ass_VS::set_right_scope(Scope
*p_scope
)
1833 right_scope
=p_scope
;
1836 Type
* Ass_VS::get_Type()
1839 error("`%s' is a parameterized value set assignment",
1840 get_fullname().c_str());
1849 if (checked
) return;
1851 Error_Context
cntxt(this, "In value set assignment `%s'",
1852 id
->get_dispname().c_str());
1854 ass_pard
->get_nof_pars();
1858 // parse the content of right and add it to left as one more constraint
1859 Node
*node
= right
->parse(KW_Block_ValueSet
);
1860 Constraint
* vs_constr
= dynamic_cast<Constraint
*>(node
);
1861 if (vs_constr
) { // if we have a constraint add it to the type
1862 if (right_scope
) { // if this is a parameter of a pard type
1863 vs_constr
->set_my_scope(right_scope
);
1865 if (!left
->get_constraints()) left
->add_constraints(new Constraints());
1866 left
->get_constraints()->add_con(vs_constr
);
1870 left
->set_genname(get_genname());
1872 ReferenceChain
refch(left
, "While checking embedded recursions");
1873 left
->chk_recursions(refch
);
1876 void Ass_VS::generate_code(output_struct
*target
, bool)
1878 left
->generate_code(target
);
1881 void Ass_VS::generate_code(CodeGenHelper
& cgh
) {
1882 if (ass_pard
|| dontgen
) return;
1883 generate_code(cgh
.get_outputstruct(left
));
1884 cgh
.finalize_generation(left
);
1887 void Ass_VS::dump(unsigned level
) const
1889 DEBUG(level
, "Value set assignment: %s%s",
1890 id
->get_dispname().c_str(), ass_pard
?"{}":"");
1899 // =================================
1901 // =================================
1903 Ass_OC::Ass_OC(Identifier
*p_id
, Ass_pard
*p_ass_pard
,
1904 ObjectClass
*p_right
)
1905 : Assignment(A_OC
, p_id
, p_ass_pard
)
1908 FATAL_ERROR("NULL parameter: Asn::Ass_OC::Ass_OC()");
1912 Ass_OC::Ass_OC(const Ass_OC
& p
)
1915 right
=p
.right
->clone();
1923 Assignment
* Ass_OC::new_instance0()
1926 (new Identifier(Identifier::ID_ASN
, string("<error>")), 0, right
->clone());
1929 void Ass_OC::set_fullname(const string
& p_fullname
)
1931 Assignment::set_fullname(p_fullname
);
1932 right
->set_fullname(p_fullname
);
1935 void Ass_OC::set_my_scope(Scope
*p_scope
)
1937 Assignment::set_my_scope(p_scope
);
1938 right
->set_my_scope(p_scope
);
1941 void Ass_OC::set_right_scope(Scope
*p_scope
)
1943 right
->set_my_scope(p_scope
);
1949 Error_Context
cntxt(this, "In information object class assignment `%s'",
1950 id
->get_dispname().c_str());
1952 ass_pard
->get_nof_pars();
1956 right
->set_genname(get_genname());
1961 ObjectClass
* Ass_OC::get_ObjectClass()
1964 error("`%s' is a parameterized objectclass assignment",
1965 get_fullname().c_str());
1972 void Ass_OC::generate_code(output_struct
*target
, bool)
1974 if (ass_pard
|| dontgen
) return;
1975 right
->generate_code(target
);
1978 void Ass_OC::generate_code(CodeGenHelper
& cgh
) {
1979 generate_code(cgh
.get_current_outputstruct());
1982 void Ass_OC::dump(unsigned level
) const
1984 DEBUG(level
, "ObjectClass assignment: %s%s",
1985 id
->get_dispname().c_str(), ass_pard
?"{}":"");
1991 // =================================
1993 // =================================
1995 Ass_O::Ass_O(Identifier
*p_id
, Ass_pard
*p_ass_pard
,
1996 ObjectClass
*p_left
, Object
*p_right
)
1997 : Assignment(A_OBJECT
, p_id
, p_ass_pard
)
1999 if(!p_left
|| !p_right
)
2000 FATAL_ERROR("NULL parameter: Asn::Ass_O::Ass_O()");
2005 Ass_O::Ass_O(const Ass_O
& p
)
2008 left
=p
.left
->clone();
2009 right
=p
.right
->clone();
2018 Assignment
* Ass_O::new_instance0()
2021 (new Identifier(Identifier::ID_ASN
, string("<error>")), 0,
2022 left
->clone(), right
->clone());
2025 void Ass_O::set_fullname(const string
& p_fullname
)
2027 Assignment::set_fullname(p_fullname
);
2028 left
->set_fullname(p_fullname
);
2029 right
->set_fullname(p_fullname
);
2032 void Ass_O::set_my_scope(Scope
*p_scope
)
2034 Assignment::set_my_scope(p_scope
);
2035 left
->set_my_scope(p_scope
);
2036 right
->set_my_scope(p_scope
);
2039 void Ass_O::set_right_scope(Scope
*p_scope
)
2041 right
->set_my_scope(p_scope
);
2045 ObjectClass* Ass_O::get_ObjectClass()
2051 Object
* Ass_O::get_Object()
2054 error("`%s' is a parameterized object assignment",
2055 get_fullname().c_str());
2065 Error_Context
cntxt(this, "In information object assignment `%s'",
2066 id
->get_dispname().c_str());
2068 ass_pard
->get_nof_pars();
2073 right
->set_my_governor(left
);
2074 right
->set_genname(get_genname());
2079 void Ass_O::generate_code(output_struct
*target
, bool)
2081 if (ass_pard
|| dontgen
) return;
2082 left
->generate_code(target
);
2083 right
->generate_code(target
);
2086 void Ass_O::generate_code(CodeGenHelper
& cgh
) {
2087 generate_code(cgh
.get_current_outputstruct());
2090 void Ass_O::dump(unsigned level
) const
2092 DEBUG(level
, "Object assignment: %s%s",
2093 id
->get_dispname().c_str(), ass_pard
?"{}":"");
2100 // =================================
2102 // =================================
2104 Ass_OS::Ass_OS(Identifier
*p_id
, Ass_pard
*p_ass_pard
,
2105 ObjectClass
*p_left
, ObjectSet
*p_right
)
2106 : Assignment(A_OS
, p_id
, p_ass_pard
)
2108 if(!p_left
|| !p_right
)
2109 FATAL_ERROR("NULL parameter: Asn::Ass_OS::Ass_OS()");
2114 Ass_OS::Ass_OS(const Ass_OS
& p
)
2117 left
=p
.left
->clone();
2118 right
=p
.right
->clone();
2127 Assignment
* Ass_OS::new_instance0()
2130 (new Identifier(Identifier::ID_ASN
, string("<error>")), 0,
2131 left
->clone(), right
->clone());
2134 void Ass_OS::set_fullname(const string
& p_fullname
)
2136 Assignment::set_fullname(p_fullname
);
2137 left
->set_fullname(p_fullname
);
2138 right
->set_fullname(p_fullname
);
2141 void Ass_OS::set_my_scope(Scope
*p_scope
)
2143 Assignment::set_my_scope(p_scope
);
2144 left
->set_my_scope(p_scope
);
2145 right
->set_my_scope(p_scope
);
2148 void Ass_OS::set_right_scope(Scope
*p_scope
)
2150 right
->set_my_scope(p_scope
);
2154 ObjectClass* Ass_OS::get_ObjectClass()
2160 ObjectSet
* Ass_OS::get_ObjectSet()
2163 error("`%s' is a parameterized objectset assignment",
2164 get_fullname().c_str());
2174 Error_Context
cntxt(this, "In information object set assignment `%s'",
2175 id
->get_dispname().c_str());
2177 ass_pard
->get_nof_pars();
2182 right
->set_my_governor(left
);
2183 right
->set_genname(get_genname());
2188 void Ass_OS::generate_code(output_struct
*target
, bool)
2190 if (ass_pard
|| dontgen
) return;
2191 left
->generate_code(target
);
2192 right
->generate_code(target
);
2195 void Ass_OS::generate_code(CodeGenHelper
& cgh
) {
2196 generate_code(cgh
.get_current_outputstruct());
2199 void Ass_OS::dump(unsigned level
) const
2201 DEBUG(level
, "ObjectSet assignment: %s%s",
2202 id
->get_dispname().c_str(), ass_pard
?"{}":"");
2209 // =================================
2211 // =================================
2213 // =================================
2215 // =================================
2217 const Identifier
* Ref_defd::get_modid()
2219 Ref_defd_simple
*t_ref
= get_ref_defd_simple();
2220 if (t_ref
) return t_ref
->get_modid();
2224 const Identifier
* Ref_defd::get_id()
2226 Ref_defd_simple
*t_ref
= get_ref_defd_simple();
2227 if (t_ref
) return t_ref
->get_id();
2231 bool Ref_defd::refers_to_st(Setting::settingtype_t p_st
,
2232 ReferenceChain
* refch
)
2234 if(get_is_erroneous()) return p_st
==Setting::S_ERROR
;
2236 Error_Context
cntxt(this, "In reference `%s'", get_dispname().c_str());
2238 FATAL_ERROR("NULL parameter");
2239 Common::Assignment
* c_ass
=my_scope
->get_ass_bySRef(this);
2244 Assignment
* ass
=dynamic_cast<Assignment
*>(c_ass
);
2246 error("Reference to a non-ASN setting");
2252 b
=ass
->is_asstype(Assignment::A_OC
, refch
);
2255 b
=ass
->is_asstype(Assignment::A_TYPE
, refch
);
2258 b
=ass
->is_asstype(Assignment::A_OBJECT
, refch
);
2261 b
=ass
->is_asstype(Assignment::A_CONST
, refch
);
2264 b
=ass
->is_asstype(Assignment::A_OS
, refch
);
2267 b
=ass
->is_asstype(Assignment::A_VS
, refch
);
2269 case Setting::S_ERROR
:
2270 b
=ass
->is_asstype(Assignment::A_ERROR
, refch
);
2273 FATAL_ERROR("Asn::Ref_defd::refers_to_st()");
2278 void Ref_defd::generate_code(expression_struct_t
*)
2280 FATAL_ERROR("Ref_defd::generate_code()");
2283 void Ref_defd::generate_code_const_ref(expression_struct */
*expr*/
)
2285 FATAL_ERROR("Ref_defd::generate_code_const_ref()");
2288 // =================================
2289 // ===== Ref_defd_simple
2290 // =================================
2292 Ref_defd_simple::Ref_defd_simple(Identifier
*p_modid
,
2294 : Ref_defd(), modid(p_modid
), id(p_id
)
2297 FATAL_ERROR("NULL parameter: Asn::Ref_defd_simple::Ref_defd_simple()");
2300 Ref_defd_simple::Ref_defd_simple(const Ref_defd_simple
& p
)
2303 modid
=p
.modid
?p
.modid
->clone():0;
2307 Ref_defd_simple::~Ref_defd_simple()
2313 Assignment
* Ref_defd_simple::get_refd_ass()
2315 if(get_is_erroneous()) return 0;
2316 Error_Context
cntxt(this, "In reference `%s'", get_dispname().c_str());
2318 FATAL_ERROR("NULL parameter: Asn::Ref_defd_simple::get_refd_ass():"
2319 " my_scope is not set");
2320 Common::Assignment
* c_ass
=my_scope
->get_ass_bySRef(this);
2321 if(!c_ass
) return 0;
2322 Assignment
* ass
=dynamic_cast<Assignment
*>(c_ass
);
2324 this->error("Reference to a non-ASN assignment");
This page took 0.082212 seconds and 6 git commands to generate.