Sync with 5.2.0
[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 if (Common::Assignment::A_TYPE == new_ass->get_asstype()) {
195 new_ass->get_Type()->set_pard_type_instance();
196 }
197
198 ref_ds=new Ref_defd_simple(new Identifier(my_mod->get_modid()),
199 new Identifier(new_ass_id));
200 ref_ds->set_fullname(get_fullname());
201 ref_ds->set_my_scope(my_mod);
202 return ref_ds;
203 }
204
205 void Ref_pard::dump(unsigned level) const
206 {
207 DEBUG(level, "Parameterized reference: %s", const_cast<Ref_pard*>(this)->get_dispname().c_str());
208 if(asss) {
209 DEBUG(level, "with parameters");
210 level++;
211 asss->dump(level);
212 }
213 }
214
215 // =================================
216 // ===== FieldName
217 // =================================
218
219 FieldName::FieldName(const FieldName& p)
220 : Node(p)
221 {
222 for(size_t i=0; i<p.fields.size(); i++)
223 add_field(p.fields[i]->clone());
224 }
225
226 FieldName::~FieldName()
227 {
228 for(size_t i=0; i<fields.size(); i++) delete fields[i];
229 fields.clear();
230 }
231
232 FieldName *FieldName::clone() const
233 {
234 return new FieldName(*this);
235 }
236
237 void FieldName::add_field(Identifier *p_id)
238 {
239 if(!p_id)
240 FATAL_ERROR("NULL parameter: Asn::FieldName::add_field()");
241 fields.add(p_id);
242 }
243
244 string FieldName::get_dispname() const
245 {
246 string s;
247 size_t nof_fields = fields.size();
248 for (size_t i = 0; i < nof_fields; i++) {
249 s += '.';
250 s += fields[i]->get_dispname();
251 }
252 return s;
253 }
254
255 // =================================
256 // ===== FromObj
257 // =================================
258
259 FromObj::FromObj(Ref_defd *p_ref_defd, FieldName *p_fn)
260 : Common::Reference(), setting(0), setting_cache(0)
261 {
262 if (!p_ref_defd || !p_fn)
263 FATAL_ERROR("NULL parameter: Asn::FromObj::FromObj()");
264 ref_defd=p_ref_defd;
265 fn=p_fn;
266 }
267
268 FromObj::FromObj(const FromObj& p)
269 : Common::Reference(p), setting(0), setting_cache(0)
270 {
271 ref_defd=p.ref_defd->clone();
272 fn=p.fn->clone();
273 }
274
275 FromObj::~FromObj()
276 {
277 delete ref_defd;
278 delete fn;
279 delete setting;
280 }
281
282 FromObj *FromObj::clone() const
283 {
284 return new FromObj(*this);
285 }
286
287 void FromObj::set_fullname(const string& p_fullname)
288 {
289 Common::Reference::set_fullname(p_fullname);
290 ref_defd->set_fullname(p_fullname);
291 fn->set_fullname(p_fullname + ".<fieldnames>");
292 }
293
294 void FromObj::set_my_scope(Scope *p_scope)
295 {
296 Common::Reference::set_my_scope(p_scope);
297 ref_defd->set_my_scope(p_scope);
298 }
299
300 string FromObj::get_dispname()
301 {
302 return ref_defd->get_dispname()+fn->get_dispname();
303 }
304
305 bool FromObj::get_is_erroneous()
306 {
307 get_refd_setting();
308 return is_erroneous;
309 }
310
311 /** \todo enhance */
312 Setting* FromObj::get_refd_setting()
313 {
314 if(setting_cache) return setting_cache;
315 Error_Context ec_0
316 (this, "In InformationFromObjects construct `%s'",
317 get_dispname().c_str());
318 enum { UNKNOWN, OC, OS, O } curr = UNKNOWN;
319 OC_defn *t_oc=0;
320 OS_defn *t_os=0;
321 Obj_defn *t_o=0;
322 OS_defn *fromobjs = 0; // temporary storage
323 size_t nof_fields = fn->get_nof_fields();
324 Setting *t_setting = ref_defd->get_refd_setting();
325 if(!t_setting) goto error;
326
327 /* the first part */
328 switch(t_setting->get_st()) {
329 case Setting::S_OS: {
330 curr=OS;
331 t_os=dynamic_cast<ObjectSet*>(t_setting)->get_refd_last();
332 t_oc=t_os->get_my_governor()->get_refd_last();
333 OSEV_objcollctr objcoll(t_os, t_oc);
334 objcoll.visit_ObjectSet(*t_os);
335 fromobjs=new OS_defn(objcoll.give_objs());
336 fromobjs->set_my_governor(t_oc);
337 break; }
338 case Setting::S_O:
339 curr=O;
340 t_o=dynamic_cast<Object*>(t_setting)->get_refd_last();
341 t_oc=t_o->get_my_governor()->get_refd_last();
342 break;
343 case Setting::S_OC:
344 curr=OC;
345 t_oc=dynamic_cast<ObjectClass*>(t_setting)->get_refd_last();
346 break;
347 case Setting::S_ERROR:
348 goto error;
349 default:
350 error("Invalid reference `%s' "
351 "(ObjectClass, ObjectSet or Object reference was expected)",
352 get_dispname().c_str());
353 goto error;
354 } // switch st
355
356 /* the middle part */
357 for(size_t i=0; i<nof_fields-1; i++) {
358 Identifier *curr_fn = fn->get_field_byIndex(i);
359 Error_Context ec_1(this, "While examining part #%lu (`%s') of FieldName",
360 (unsigned long) (i + 1), curr_fn->get_dispname().c_str());
361 FieldSpec *curr_fspec =
362 t_oc->get_fss()->get_fs_byId(*curr_fn)->get_last();
363 if(curr_fspec->get_fstype()==FieldSpec::FS_ERROR) goto error;
364 switch(curr) {
365 case OC:
366 switch(curr_fspec->get_fstype()) {
367 case FieldSpec::FS_O: {
368 FieldSpec_O *tmp_fspec=
369 dynamic_cast<FieldSpec_O*>(curr_fspec);
370 t_oc=tmp_fspec->get_oc()->get_refd_last();
371 break;}
372 case FieldSpec::FS_OS: {
373 FieldSpec_OS *tmp_fspec=
374 dynamic_cast<FieldSpec_OS*>(curr_fspec);
375 t_oc=tmp_fspec->get_oc()->get_refd_last();
376 break;}
377 case FieldSpec::FS_ERROR:
378 goto error;
379 default:
380 error("This notation is not permitted (object or objectset"
381 " fieldreference was expected)");
382 goto error;
383 } // switch fspec.fstype
384 break;
385 case OS:
386 switch(curr_fspec->get_fstype()) {
387 case FieldSpec::FS_O: {
388 FieldSpec_O *tmp_fspec=
389 dynamic_cast<FieldSpec_O*>(curr_fspec);
390 t_oc=tmp_fspec->get_oc()->get_refd_last();
391 OSEV_objcollctr objcoll(this, t_oc);
392 Objects *t_objs = fromobjs->get_objs();
393 for(size_t j=0; j<t_objs->get_nof_objs(); j++) {
394 t_o=t_objs->get_obj_byIndex(j)->get_refd_last();
395 if(!t_o->has_fs_withName_dflt(*curr_fn)) continue;
396 t_setting=t_o->get_setting_byName_dflt(*curr_fn);
397 t_o=dynamic_cast<Object*>(t_setting)->get_refd_last();
398 objcoll.visit_Object(*t_o);
399 }
400 delete fromobjs;
401 fromobjs=new OS_defn(objcoll.give_objs());
402 fromobjs->set_location(*this);
403 fromobjs->set_my_governor(t_oc);
404 break;}
405 case FieldSpec::FS_OS: {
406 FieldSpec_OS *tmp_fspec=
407 dynamic_cast<FieldSpec_OS*>(curr_fspec);
408 t_oc=tmp_fspec->get_oc()->get_refd_last();
409 OSEV_objcollctr objcoll(this, t_oc);
410 Objects *t_objs = fromobjs->get_objs();
411 for(size_t j=0; j<t_objs->get_nof_objs(); j++) {
412 t_o=t_objs->get_obj_byIndex(j)->get_refd_last();
413 if(!t_o->has_fs_withName_dflt(*curr_fn)) continue;
414 t_setting=t_o->get_setting_byName_dflt(*curr_fn);
415 t_os=dynamic_cast<ObjectSet*>(t_setting)->get_refd_last();
416 objcoll.visit_ObjectSet(*t_os);
417 }
418 delete fromobjs;
419 fromobjs=new OS_defn(objcoll.give_objs());
420 fromobjs->set_location(*this);
421 fromobjs->set_my_governor(t_oc);
422 break;}
423 case FieldSpec::FS_ERROR:
424 goto error;
425 default:
426 error("This notation is not permitted (object or objectset"
427 " fieldreference was expected)");
428 goto error;
429 } // switch fspec.fstype
430 break;
431 case O:
432 switch(curr_fspec->get_fstype()) {
433 case FieldSpec::FS_O: {
434 FieldSpec_O *tmp_fspec=
435 dynamic_cast<FieldSpec_O*>(curr_fspec);
436 t_oc=tmp_fspec->get_oc()->get_refd_last();
437 t_setting=t_o->get_setting_byName_dflt(*curr_fn);
438 t_o=dynamic_cast<Object*>(t_setting)->get_refd_last();
439 break;}
440 case FieldSpec::FS_OS: {
441 curr=OS;
442 FieldSpec_OS *tmp_fspec=
443 dynamic_cast<FieldSpec_OS*>(curr_fspec);
444 t_oc=tmp_fspec->get_oc()->get_refd_last();
445 OSEV_objcollctr objcoll(*fromobjs);
446 Objects *t_objs = fromobjs->get_objs();
447 for(size_t j=0; j<t_objs->get_nof_objs(); j++) {
448 t_o=t_objs->get_obj_byIndex(j)->get_refd_last();
449 if(!t_o->has_fs_withName_dflt(*curr_fn)) continue;
450 t_setting=t_o->get_setting_byName_dflt(*curr_fn);
451 t_os=dynamic_cast<ObjectSet*>(t_setting)->get_refd_last();
452 objcoll.visit_ObjectSet(*t_os);
453 }
454 delete fromobjs;
455 fromobjs=new OS_defn(objcoll.give_objs());
456 fromobjs->set_location(*this);
457 fromobjs->set_my_governor(t_oc);
458 break;}
459 case FieldSpec::FS_ERROR:
460 goto error;
461 default:
462 error("This notation is not permitted (object or objectset"
463 " fieldreference was expected)");
464 goto error;
465 } // switch fspec.fstype
466 break;
467 default:
468 FATAL_ERROR("Asn::FromObj::get_refd_setting()");
469 } // switch curr
470 } // for i
471
472 /* and the last part... */
473 {
474 Identifier *curr_fn = fn->get_field_byIndex(nof_fields-1);
475 Error_Context ec_1
476 (this,
477 "While examining last part (`%s') of FieldName",
478 curr_fn->get_dispname().c_str());
479 FieldSpec *curr_fspec =
480 t_oc->get_fss()->get_fs_byId(*curr_fn)->get_last();
481 switch(curr) {
482 case OC:
483 switch(curr_fspec->get_fstype()) {
484 case FieldSpec::FS_T: {
485 Type *opentype = new Type(Type::T_OPENTYPE, t_oc, curr_fn);
486 opentype->set_location(*this);
487 setting = opentype;
488 break; }
489 case FieldSpec::FS_V_FT: {
490 FieldSpec_V_FT *tmp_fspec=
491 dynamic_cast<FieldSpec_V_FT*>(curr_fspec);
492 Type *ocft =
493 new Type(Type::T_OCFT, tmp_fspec->get_type(), t_oc, curr_fn);
494 ocft->set_location(*this);
495 setting = ocft;
496 break;}
497 case FieldSpec::FS_V_VT:
498 case FieldSpec::FS_VS_FT:
499 case FieldSpec::FS_VS_VT:
500 error("Sorry, this construct is not supported");
501 goto error;
502 case FieldSpec::FS_O:
503 case FieldSpec::FS_OS:
504 error("This notation is not permitted (type, (fixed- or"
505 " variabletype) value or valueset fieldreference was"
506 " expected)");
507 // no break
508 case FieldSpec::FS_ERROR:
509 goto error;
510 default:
511 FATAL_ERROR("Unhandled fieldspec type");
512 } // switch fspec.fstype
513 break;
514 case OS:
515 switch(curr_fspec->get_fstype()) {
516 case FieldSpec::FS_O: {
517 FieldSpec_O *tmp_fspec=
518 dynamic_cast<FieldSpec_O*>(curr_fspec);
519 t_oc=tmp_fspec->get_oc()->get_refd_last();
520 OSEV_objcollctr objcoll(this, t_oc);
521 Objects *t_objs = fromobjs->get_objs();
522 for(size_t j=0; j<t_objs->get_nof_objs(); j++) {
523 t_o=t_objs->get_obj_byIndex(j)->get_refd_last();
524 if(!t_o->has_fs_withName_dflt(*curr_fn)) continue;
525 t_setting=t_o->get_setting_byName_dflt(*curr_fn);
526 t_o=dynamic_cast<Object*>(t_setting)->get_refd_last();
527 objcoll.visit_Object(*t_o);
528 }
529 delete fromobjs;
530 fromobjs=new OS_defn(objcoll.give_objs());
531 fromobjs->set_location(*this);
532 fromobjs->set_my_governor(t_oc);
533 fromobjs->set_my_scope(my_scope);
534 setting = fromobjs;
535 break;}
536 case FieldSpec::FS_OS: {
537 FieldSpec_OS *tmp_fspec=
538 dynamic_cast<FieldSpec_OS*>(curr_fspec);
539 t_oc=tmp_fspec->get_oc()->get_refd_last();
540 OSEV_objcollctr objcoll(this, t_oc);
541 Objects *t_objs = fromobjs->get_objs();
542 for(size_t j=0; j<t_objs->get_nof_objs(); j++) {
543 t_o=t_objs->get_obj_byIndex(j)->get_refd_last();
544 if(!t_o->has_fs_withName_dflt(*curr_fn)) continue;
545 t_setting=t_o->get_setting_byName_dflt(*curr_fn);
546 t_os=dynamic_cast<ObjectSet*>(t_setting)->get_refd_last();
547 objcoll.visit_ObjectSet(*t_os);
548 }
549 delete fromobjs;
550 fromobjs=new OS_defn(objcoll.give_objs());
551 fromobjs->set_location(*this);
552 fromobjs->set_my_governor(t_oc);
553 fromobjs->set_my_scope(my_scope);
554 setting = fromobjs;
555 break;}
556 case FieldSpec::FS_V_FT:
557 case FieldSpec::FS_VS_FT:
558 error("Sorry, ValueSetFromObjects not supported");
559 // no break
560 case FieldSpec::FS_ERROR:
561 goto error;
562 default:
563 error("This notation is not permitted (object, objectset,"
564 " (fixed type) value or valueset fieldreference was"
565 " expected)");
566 goto error;
567 } // switch fspec.fstype
568 break;
569 case O:
570 setting_cache = t_o->get_setting_byName_dflt(*curr_fn);
571 break;
572 default:
573 FATAL_ERROR("Asn::FromObj::get_refd_setting()");
574 } // switch curr
575 } // errorcontext-block
576 if (!setting_cache) setting_cache = setting;
577 goto end;
578 error:
579 delete fromobjs;
580 is_erroneous=true;
581 setting_cache=get_refd_setting_error();
582 end:
583 return setting_cache;
584 }
585
586 Common::Assignment* FromObj::get_refd_assignment(bool check_parlist)
587 {
588 return ref_defd->get_refd_assignment(check_parlist);
589 }
590
591 bool FromObj::has_single_expr()
592 {
593 FATAL_ERROR("FromObj::has_single_expr()");
594 return false;
595 }
596
597 void FromObj::generate_code(expression_struct_t *)
598 {
599 FATAL_ERROR("FromObj::generate_code()");
600 }
601
602 void FromObj::generate_code_const_ref(expression_struct_t */*expr*/)
603 {
604 FATAL_ERROR("FromObj::generate_code_const_ref()");
605 }
606
607 } // namespace Asn
This page took 0.063048 seconds and 5 git commands to generate.