b933ea174f9220433dd5e6315410ee7f138f489f
[deliverable/titan.core.git] / compiler2 / asn1 / Ref.cc
1 ///////////////////////////////////////////////////////////////////////////////
2 // Copyright (c) 2000-2014 Ericsson Telecom AB
3 // All rights reserved. This program and the accompanying materials
4 // are made available under the terms of the Eclipse Public License v1.0
5 // which accompanies this distribution, and is available at
6 // http://www.eclipse.org/legal/epl-v10.html
7 ///////////////////////////////////////////////////////////////////////////////
8 #include "Ref.hh"
9 #include "../Identifier.hh"
10 #include "AST_asn1.hh"
11 #include "Block.hh"
12 #include "TokenBuf.hh"
13
14 namespace Asn {
15
16 // =================================
17 // ===== Ref_pard
18 // =================================
19
20 Ref_pard::Ref_pard(Ref_defd_simple *p_refds, Block *p_block)
21 : Ref_defd(), ref_parass(p_refds), block(p_block),
22 refd_ass_is_not_pard(false), asss(0), ref_ds(0)
23 {
24 if (!p_refds || !p_block)
25 FATAL_ERROR("NULL parameter: Asn::Ref_pard::Ref_pard()");
26 }
27
28 Ref_pard::Ref_pard(const Ref_pard& p)
29 : Ref_defd(p), refd_ass_is_not_pard(p.refd_ass_is_not_pard),
30 asss(0), ref_ds(0)
31 {
32 ref_parass = p.ref_parass->clone();
33 block=p.block?p.block->clone():0;
34 asss=p.asss?p.asss->clone():0;
35 }
36
37 Ref_pard::~Ref_pard()
38 {
39 delete ref_parass;
40 delete block;
41 delete asss;
42 delete ref_ds;
43 }
44
45 Ref_pard *Ref_pard::clone() const
46 {
47 return new Ref_pard(*this);
48 }
49
50 void Ref_pard::set_fullname(const string& p_fullname)
51 {
52 Ref_defd::set_fullname(p_fullname);
53 ref_parass->set_fullname(p_fullname);
54 if (block) block->set_fullname(p_fullname + ".<block>");
55 if (asss) asss->set_fullname(p_fullname + "." +
56 ref_parass->get_dispname() + "{}");
57 if (ref_ds) ref_ds->set_fullname(p_fullname);
58 }
59
60 void Ref_pard::set_my_scope(Scope *p_scope)
61 {
62 Ref_defd::set_my_scope(p_scope);
63 ref_parass->set_my_scope(p_scope);
64 if (ref_ds) ref_ds->set_my_scope(p_scope);
65 }
66
67 bool Ref_pard::get_is_erroneous()
68 {
69 get_ref_defd_simple();
70 return is_erroneous;
71 }
72
73 string Ref_pard::get_dispname()
74 {
75 if (ref_ds) return ref_ds->get_dispname();
76 else return ref_parass->get_dispname()+"{}";
77 }
78
79 Ref_defd_simple* Ref_pard::get_ref_defd_simple()
80 {
81 if(ref_ds) return ref_ds;
82 if(is_erroneous) return 0;
83 if(refd_ass_is_not_pard) return ref_parass;
84 Module *my_mod = dynamic_cast<Module*>(my_scope->get_scope_mod());
85 if(!my_mod) FATAL_ERROR("Asn::Ref_pard::get_ref_defd_simple()");
86
87 /* search the referenced parameterized assignment */
88 Assignment *parass=ref_parass->get_refd_ass();
89 if(!parass) {
90 is_erroneous=true;
91 delete block;
92 block=0;
93 return 0;
94 }
95 Ass_pard *ass_pard=parass->get_ass_pard();
96 if(!ass_pard) {
97 /* error: this is not a parameterized assignment */
98 refd_ass_is_not_pard=true;
99 delete block;
100 block=0;
101 return ref_parass;
102 }
103 size_t nof_formal_pars=ass_pard->get_nof_pars();
104 if(nof_formal_pars==0) {
105 /* error in parameterized assignment */
106 is_erroneous=true;
107 return 0;
108 }
109
110 Error_Context cntxt
111 (this, "While instantiating parameterized reference `%s'",
112 ref_parass->get_dispname().c_str());
113
114 if(block) {
115 /* splitting the actual parameterlist */
116 vector<TokenBuf> act_pars; // actual parameters
117 {
118 TokenBuf *act_pars_tb=block->get_TokenBuf();
119 TokenBuf *tmp_tb=new TokenBuf();
120 for(bool ok=false; !ok; ) {
121 Token *token=act_pars_tb->pop_front_token();
122 switch(token->get_token()) {
123 case '\0': // EOF
124 ok=true;
125 // no break
126 case ',':
127 token->set_token('\0');
128 tmp_tb->push_back_token(token);
129 act_pars.add(tmp_tb);
130 tmp_tb=new TokenBuf();
131 break;
132 default:
133 tmp_tb->push_back_token(token);
134 } // switch(token->token)
135 }
136 delete tmp_tb;
137 delete block;
138 block=0;
139 }
140
141 /* checking the number of parameters */
142 size_t nof_act_pars=act_pars.size();
143 if(nof_act_pars != nof_formal_pars)
144 error("Too %s parameters: %lu was expected instead of %lu",
145 nof_act_pars<nof_formal_pars?"few":"many",
146 (unsigned long) nof_formal_pars, (unsigned long) nof_act_pars);
147
148 /* building the new assignments */
149 asss=new Assignments();
150 for(size_t i=0; i<nof_formal_pars; i++) {
151 const Identifier& tmp_id=ass_pard->get_nth_dummyref(i);
152 Error_Context cntxt2(this, "While examining parameter `%s'",
153 tmp_id.get_dispname().c_str());
154 Assignment *tmp_ass=0;
155 if(i<nof_act_pars) {
156 TokenBuf *tmp_tb=ass_pard->clone_nth_governor(i);
157 tmp_tb->move_tokens_from(act_pars[i]);
158 tmp_tb->push_back_kw_token('\0');
159 Block *tmp_block=new Block(tmp_tb);
160 Node *tmp_node=tmp_block->parse(KW_Block_Assignment);
161 delete tmp_block;
162 tmp_ass=dynamic_cast<Assignment*>(tmp_node);
163 if(!tmp_ass) delete tmp_node;
164 }
165 // substitution of missing parameters (for error recovery)
166 if(!tmp_ass) tmp_ass=new Ass_Error(tmp_id.clone(), 0);
167 tmp_ass->set_location(*this);
168 asss->add_ass(tmp_ass);
169 } // for i
170
171 for(size_t i=0; i<nof_act_pars; i++) delete act_pars[i];
172 act_pars.clear();
173 }
174
175 Assignment *new_ass = parass->new_instance(my_scope->get_scope_mod_gen());
176 my_mod->add_ass(new_ass);
177 const Identifier& new_ass_id = new_ass->get_id();
178 const string& new_ass_dispname = new_ass_id.get_dispname();
179
180 asss->set_right_scope(my_scope);
181 asss->set_parent_scope(parass->get_my_scope());
182 asss->set_parent_scope_gen(my_scope);
183 asss->set_scope_name(new_ass_dispname);
184 asss->set_fullname(get_fullname() + "." + ref_parass->get_dispname() +
185 "{}");
186 asss->chk();
187
188 new_ass->set_fullname(my_mod->get_fullname() + "." + new_ass_dispname);
189 new_ass->set_my_scope(asss);
190 new_ass->set_location(*this);
191 new_ass->set_dontgen();
192 new_ass->chk();
193
194 ref_ds=new Ref_defd_simple(new Identifier(my_mod->get_modid()),
195 new Identifier(new_ass_id));
196 ref_ds->set_fullname(get_fullname());
197 ref_ds->set_my_scope(my_mod);
198 return ref_ds;
199 }
200
201 void Ref_pard::dump(unsigned level) const
202 {
203 DEBUG(level, "Parameterized reference: %s", const_cast<Ref_pard*>(this)->get_dispname().c_str());
204 if(asss) {
205 DEBUG(level, "with parameters");
206 level++;
207 asss->dump(level);
208 }
209 }
210
211 // =================================
212 // ===== FieldName
213 // =================================
214
215 FieldName::FieldName(const FieldName& p)
216 : Node(p)
217 {
218 for(size_t i=0; i<p.fields.size(); i++)
219 add_field(p.fields[i]->clone());
220 }
221
222 FieldName::~FieldName()
223 {
224 for(size_t i=0; i<fields.size(); i++) delete fields[i];
225 fields.clear();
226 }
227
228 FieldName *FieldName::clone() const
229 {
230 return new FieldName(*this);
231 }
232
233 void FieldName::add_field(Identifier *p_id)
234 {
235 if(!p_id)
236 FATAL_ERROR("NULL parameter: Asn::FieldName::add_field()");
237 fields.add(p_id);
238 }
239
240 string FieldName::get_dispname() const
241 {
242 string s;
243 size_t nof_fields = fields.size();
244 for (size_t i = 0; i < nof_fields; i++) {
245 s += '.';
246 s += fields[i]->get_dispname();
247 }
248 return s;
249 }
250
251 // =================================
252 // ===== FromObj
253 // =================================
254
255 FromObj::FromObj(Ref_defd *p_ref_defd, FieldName *p_fn)
256 : Common::Reference(), setting(0), setting_cache(0)
257 {
258 if (!p_ref_defd || !p_fn)
259 FATAL_ERROR("NULL parameter: Asn::FromObj::FromObj()");
260 ref_defd=p_ref_defd;
261 fn=p_fn;
262 }
263
264 FromObj::FromObj(const FromObj& p)
265 : Common::Reference(p), setting(0), setting_cache(0)
266 {
267 ref_defd=p.ref_defd->clone();
268 fn=p.fn->clone();
269 }
270
271 FromObj::~FromObj()
272 {
273 delete ref_defd;
274 delete fn;
275 delete setting;
276 }
277
278 FromObj *FromObj::clone() const
279 {
280 return new FromObj(*this);
281 }
282
283 void FromObj::set_fullname(const string& p_fullname)
284 {
285 Common::Reference::set_fullname(p_fullname);
286 ref_defd->set_fullname(p_fullname);
287 fn->set_fullname(p_fullname + ".<fieldnames>");
288 }
289
290 void FromObj::set_my_scope(Scope *p_scope)
291 {
292 Common::Reference::set_my_scope(p_scope);
293 ref_defd->set_my_scope(p_scope);
294 }
295
296 string FromObj::get_dispname()
297 {
298 return ref_defd->get_dispname()+fn->get_dispname();
299 }
300
301 bool FromObj::get_is_erroneous()
302 {
303 get_refd_setting();
304 return is_erroneous;
305 }
306
307 /** \todo enhance */
308 Setting* FromObj::get_refd_setting()
309 {
310 if(setting_cache) return setting_cache;
311 Error_Context ec_0
312 (this, "In InformationFromObjects construct `%s'",
313 get_dispname().c_str());
314 enum { UNKNOWN, OC, OS, O } curr = UNKNOWN;
315 OC_defn *t_oc=0;
316 OS_defn *t_os=0;
317 Obj_defn *t_o=0;
318 OS_defn *fromobjs = 0; // temporary storage
319 size_t nof_fields = fn->get_nof_fields();
320 Setting *t_setting = ref_defd->get_refd_setting();
321 if(!t_setting) goto error;
322
323 /* the first part */
324 switch(t_setting->get_st()) {
325 case Setting::S_OS: {
326 curr=OS;
327 t_os=dynamic_cast<ObjectSet*>(t_setting)->get_refd_last();
328 t_oc=t_os->get_my_governor()->get_refd_last();
329 OSEV_objcollctr objcoll(t_os, t_oc);
330 objcoll.visit_ObjectSet(*t_os);
331 fromobjs=new OS_defn(objcoll.give_objs());
332 fromobjs->set_my_governor(t_oc);
333 break; }
334 case Setting::S_O:
335 curr=O;
336 t_o=dynamic_cast<Object*>(t_setting)->get_refd_last();
337 t_oc=t_o->get_my_governor()->get_refd_last();
338 break;
339 case Setting::S_OC:
340 curr=OC;
341 t_oc=dynamic_cast<ObjectClass*>(t_setting)->get_refd_last();
342 break;
343 case Setting::S_ERROR:
344 goto error;
345 default:
346 error("Invalid reference `%s' "
347 "(ObjectClass, ObjectSet or Object reference was expected)",
348 get_dispname().c_str());
349 goto error;
350 } // switch st
351
352 /* the middle part */
353 for(size_t i=0; i<nof_fields-1; i++) {
354 Identifier *curr_fn = fn->get_field_byIndex(i);
355 Error_Context ec_1(this, "While examining part #%lu (`%s') of FieldName",
356 (unsigned long) (i + 1), curr_fn->get_dispname().c_str());
357 FieldSpec *curr_fspec =
358 t_oc->get_fss()->get_fs_byId(*curr_fn)->get_last();
359 if(curr_fspec->get_fstype()==FieldSpec::FS_ERROR) goto error;
360 switch(curr) {
361 case OC:
362 switch(curr_fspec->get_fstype()) {
363 case FieldSpec::FS_O: {
364 FieldSpec_O *tmp_fspec=
365 dynamic_cast<FieldSpec_O*>(curr_fspec);
366 t_oc=tmp_fspec->get_oc()->get_refd_last();
367 break;}
368 case FieldSpec::FS_OS: {
369 FieldSpec_OS *tmp_fspec=
370 dynamic_cast<FieldSpec_OS*>(curr_fspec);
371 t_oc=tmp_fspec->get_oc()->get_refd_last();
372 break;}
373 case FieldSpec::FS_ERROR:
374 goto error;
375 default:
376 error("This notation is not permitted (object or objectset"
377 " fieldreference was expected)");
378 goto error;
379 } // switch fspec.fstype
380 break;
381 case OS:
382 switch(curr_fspec->get_fstype()) {
383 case FieldSpec::FS_O: {
384 FieldSpec_O *tmp_fspec=
385 dynamic_cast<FieldSpec_O*>(curr_fspec);
386 t_oc=tmp_fspec->get_oc()->get_refd_last();
387 OSEV_objcollctr objcoll(this, t_oc);
388 Objects *t_objs = fromobjs->get_objs();
389 for(size_t j=0; j<t_objs->get_nof_objs(); j++) {
390 t_o=t_objs->get_obj_byIndex(j)->get_refd_last();
391 if(!t_o->has_fs_withName_dflt(*curr_fn)) continue;
392 t_setting=t_o->get_setting_byName_dflt(*curr_fn);
393 t_o=dynamic_cast<Object*>(t_setting)->get_refd_last();
394 objcoll.visit_Object(*t_o);
395 }
396 delete fromobjs;
397 fromobjs=new OS_defn(objcoll.give_objs());
398 fromobjs->set_location(*this);
399 fromobjs->set_my_governor(t_oc);
400 break;}
401 case FieldSpec::FS_OS: {
402 FieldSpec_OS *tmp_fspec=
403 dynamic_cast<FieldSpec_OS*>(curr_fspec);
404 t_oc=tmp_fspec->get_oc()->get_refd_last();
405 OSEV_objcollctr objcoll(this, t_oc);
406 Objects *t_objs = fromobjs->get_objs();
407 for(size_t j=0; j<t_objs->get_nof_objs(); j++) {
408 t_o=t_objs->get_obj_byIndex(j)->get_refd_last();
409 if(!t_o->has_fs_withName_dflt(*curr_fn)) continue;
410 t_setting=t_o->get_setting_byName_dflt(*curr_fn);
411 t_os=dynamic_cast<ObjectSet*>(t_setting)->get_refd_last();
412 objcoll.visit_ObjectSet(*t_os);
413 }
414 delete fromobjs;
415 fromobjs=new OS_defn(objcoll.give_objs());
416 fromobjs->set_location(*this);
417 fromobjs->set_my_governor(t_oc);
418 break;}
419 case FieldSpec::FS_ERROR:
420 goto error;
421 default:
422 error("This notation is not permitted (object or objectset"
423 " fieldreference was expected)");
424 goto error;
425 } // switch fspec.fstype
426 break;
427 case O:
428 switch(curr_fspec->get_fstype()) {
429 case FieldSpec::FS_O: {
430 FieldSpec_O *tmp_fspec=
431 dynamic_cast<FieldSpec_O*>(curr_fspec);
432 t_oc=tmp_fspec->get_oc()->get_refd_last();
433 t_setting=t_o->get_setting_byName_dflt(*curr_fn);
434 t_o=dynamic_cast<Object*>(t_setting)->get_refd_last();
435 break;}
436 case FieldSpec::FS_OS: {
437 curr=OS;
438 FieldSpec_OS *tmp_fspec=
439 dynamic_cast<FieldSpec_OS*>(curr_fspec);
440 t_oc=tmp_fspec->get_oc()->get_refd_last();
441 OSEV_objcollctr objcoll(*fromobjs);
442 Objects *t_objs = fromobjs->get_objs();
443 for(size_t j=0; j<t_objs->get_nof_objs(); j++) {
444 t_o=t_objs->get_obj_byIndex(j)->get_refd_last();
445 if(!t_o->has_fs_withName_dflt(*curr_fn)) continue;
446 t_setting=t_o->get_setting_byName_dflt(*curr_fn);
447 t_os=dynamic_cast<ObjectSet*>(t_setting)->get_refd_last();
448 objcoll.visit_ObjectSet(*t_os);
449 }
450 delete fromobjs;
451 fromobjs=new OS_defn(objcoll.give_objs());
452 fromobjs->set_location(*this);
453 fromobjs->set_my_governor(t_oc);
454 break;}
455 case FieldSpec::FS_ERROR:
456 goto error;
457 default:
458 error("This notation is not permitted (object or objectset"
459 " fieldreference was expected)");
460 goto error;
461 } // switch fspec.fstype
462 break;
463 default:
464 FATAL_ERROR("Asn::FromObj::get_refd_setting()");
465 } // switch curr
466 } // for i
467
468 /* and the last part... */
469 {
470 Identifier *curr_fn = fn->get_field_byIndex(nof_fields-1);
471 Error_Context ec_1
472 (this,
473 "While examining last part (`%s') of FieldName",
474 curr_fn->get_dispname().c_str());
475 FieldSpec *curr_fspec =
476 t_oc->get_fss()->get_fs_byId(*curr_fn)->get_last();
477 switch(curr) {
478 case OC:
479 switch(curr_fspec->get_fstype()) {
480 case FieldSpec::FS_T: {
481 Type *opentype = new Type(Type::T_OPENTYPE, t_oc, curr_fn);
482 opentype->set_location(*this);
483 setting = opentype;
484 break; }
485 case FieldSpec::FS_V_FT: {
486 FieldSpec_V_FT *tmp_fspec=
487 dynamic_cast<FieldSpec_V_FT*>(curr_fspec);
488 Type *ocft =
489 new Type(Type::T_OCFT, tmp_fspec->get_type(), t_oc, curr_fn);
490 ocft->set_location(*this);
491 setting = ocft;
492 break;}
493 case FieldSpec::FS_V_VT:
494 case FieldSpec::FS_VS_FT:
495 case FieldSpec::FS_VS_VT:
496 error("Sorry, this construct is not supported");
497 goto error;
498 case FieldSpec::FS_O:
499 case FieldSpec::FS_OS:
500 error("This notation is not permitted (type, (fixed- or"
501 " variabletype) value or valueset fieldreference was"
502 " expected)");
503 // no break
504 case FieldSpec::FS_ERROR:
505 goto error;
506 default:
507 FATAL_ERROR("Unhandled fieldspec type");
508 } // switch fspec.fstype
509 break;
510 case OS:
511 switch(curr_fspec->get_fstype()) {
512 case FieldSpec::FS_O: {
513 FieldSpec_O *tmp_fspec=
514 dynamic_cast<FieldSpec_O*>(curr_fspec);
515 t_oc=tmp_fspec->get_oc()->get_refd_last();
516 OSEV_objcollctr objcoll(this, t_oc);
517 Objects *t_objs = fromobjs->get_objs();
518 for(size_t j=0; j<t_objs->get_nof_objs(); j++) {
519 t_o=t_objs->get_obj_byIndex(j)->get_refd_last();
520 if(!t_o->has_fs_withName_dflt(*curr_fn)) continue;
521 t_setting=t_o->get_setting_byName_dflt(*curr_fn);
522 t_o=dynamic_cast<Object*>(t_setting)->get_refd_last();
523 objcoll.visit_Object(*t_o);
524 }
525 delete fromobjs;
526 fromobjs=new OS_defn(objcoll.give_objs());
527 fromobjs->set_location(*this);
528 fromobjs->set_my_governor(t_oc);
529 fromobjs->set_my_scope(my_scope);
530 setting = fromobjs;
531 break;}
532 case FieldSpec::FS_OS: {
533 FieldSpec_OS *tmp_fspec=
534 dynamic_cast<FieldSpec_OS*>(curr_fspec);
535 t_oc=tmp_fspec->get_oc()->get_refd_last();
536 OSEV_objcollctr objcoll(this, t_oc);
537 Objects *t_objs = fromobjs->get_objs();
538 for(size_t j=0; j<t_objs->get_nof_objs(); j++) {
539 t_o=t_objs->get_obj_byIndex(j)->get_refd_last();
540 if(!t_o->has_fs_withName_dflt(*curr_fn)) continue;
541 t_setting=t_o->get_setting_byName_dflt(*curr_fn);
542 t_os=dynamic_cast<ObjectSet*>(t_setting)->get_refd_last();
543 objcoll.visit_ObjectSet(*t_os);
544 }
545 delete fromobjs;
546 fromobjs=new OS_defn(objcoll.give_objs());
547 fromobjs->set_location(*this);
548 fromobjs->set_my_governor(t_oc);
549 fromobjs->set_my_scope(my_scope);
550 setting = fromobjs;
551 break;}
552 case FieldSpec::FS_V_FT:
553 case FieldSpec::FS_VS_FT:
554 error("Sorry, ValueSetFromObjects not supported");
555 // no break
556 case FieldSpec::FS_ERROR:
557 goto error;
558 default:
559 error("This notation is not permitted (object, objectset,"
560 " (fixed type) value or valueset fieldreference was"
561 " expected)");
562 goto error;
563 } // switch fspec.fstype
564 break;
565 case O:
566 setting_cache = t_o->get_setting_byName_dflt(*curr_fn);
567 break;
568 default:
569 FATAL_ERROR("Asn::FromObj::get_refd_setting()");
570 } // switch curr
571 } // errorcontext-block
572 if (!setting_cache) setting_cache = setting;
573 goto end;
574 error:
575 delete fromobjs;
576 is_erroneous=true;
577 setting_cache=get_refd_setting_error();
578 end:
579 return setting_cache;
580 }
581
582 Common::Assignment* FromObj::get_refd_assignment(bool check_parlist)
583 {
584 return ref_defd->get_refd_assignment(check_parlist);
585 }
586
587 bool FromObj::has_single_expr()
588 {
589 FATAL_ERROR("FromObj::has_single_expr()");
590 return false;
591 }
592
593 void FromObj::generate_code(expression_struct_t *)
594 {
595 FATAL_ERROR("FromObj::generate_code()");
596 }
597
598 void FromObj::generate_code_const_ref(expression_struct_t */*expr*/)
599 {
600 FATAL_ERROR("FromObj::generate_code_const_ref()");
601 }
602
603 } // namespace Asn
This page took 0.080586 seconds and 4 git commands to generate.