Merge pull request #2303 from jwillemsen/jwi-803
[ACE_TAO.git] / TAO / TAO_IDL / ast / ast_visitor_reifying.cpp
blobe0f41fff792f551505e61dfc037c8277d4c74be2
1 /**
2 * @file ast_visitor_reifying.cpp
4 * @author Jeff Parsons
5 */
6 //=============================================================================
8 #include "ast_visitor_reifying.h"
9 #include "ast_visitor_context.h"
10 #include "ast_generator.h"
12 #include "ast_interface.h"
13 #include "ast_valuetype.h"
14 #include "ast_valuebox.h"
15 #include "ast_eventtype.h"
16 #include "ast_connector.h"
17 #include "ast_home.h"
18 #include "ast_exception.h"
19 #include "ast_typedef.h"
20 #include "ast_array.h"
21 #include "ast_sequence.h"
22 #include "ast_map.h"
23 #include "ast_union.h"
24 #include "ast_enum.h"
25 #include "ast_predefined_type.h"
26 #include "ast_string.h"
27 #include "ast_constant.h"
28 #include "ast_native.h"
29 #include "ast_param_holder.h"
30 #include "ast_template_module.h"
32 #include "utl_identifier.h"
33 #include "utl_exprlist.h"
34 #include "utl_strlist.h"
35 #include "utl_string.h"
36 #include "nr_extern.h"
38 ast_visitor_reifying::ast_visitor_reifying (
39 ast_visitor_context *ctx)
40 : ast_visitor (),
41 ctx_ (ctx),
42 reified_node_ (nullptr)
46 ast_visitor_reifying::~ast_visitor_reifying ()
50 AST_Decl *
51 ast_visitor_reifying::reified_node () const
53 return this->reified_node_;
56 int ast_visitor_reifying::visit_decl (AST_Decl *)
58 return 0;
61 int
62 ast_visitor_reifying::visit_scope (UTL_Scope *)
64 return 0;
67 int
68 ast_visitor_reifying::visit_type (AST_Type *)
70 return 0;
73 int
74 ast_visitor_reifying::visit_module (AST_Module *)
76 return 0;
79 int
80 ast_visitor_reifying::visit_interface_fwd (AST_InterfaceFwd *)
82 return 0;
85 int
86 ast_visitor_reifying::visit_valuebox (AST_ValueBox *node)
88 this->check_and_store (node);
89 return 0;
92 int
93 ast_visitor_reifying::visit_valuetype_fwd (AST_ValueTypeFwd *)
95 return 0;
98 int
99 ast_visitor_reifying::visit_eventtype_fwd (AST_EventTypeFwd *)
101 return 0;
105 ast_visitor_reifying::visit_component_fwd (AST_ComponentFwd *)
107 return 0;
111 ast_visitor_reifying::visit_template_module (AST_Template_Module *)
113 return 0;
117 ast_visitor_reifying::visit_template_module_inst (AST_Template_Module_Inst *)
119 return 0;
123 ast_visitor_reifying::visit_template_module_ref (AST_Template_Module_Ref *)
125 return 0;
129 ast_visitor_reifying::visit_porttype (AST_PortType *node)
131 this->check_and_store (node);
132 return 0;
136 ast_visitor_reifying::visit_provides (AST_Provides *)
138 return 0;
142 ast_visitor_reifying::visit_uses (AST_Uses *)
144 return 0;
148 ast_visitor_reifying::visit_publishes (AST_Publishes *)
150 return 0;
154 ast_visitor_reifying::visit_emits (AST_Emits *)
156 return 0;
160 ast_visitor_reifying::visit_consumes (AST_Consumes *)
162 return 0;
166 ast_visitor_reifying::visit_extended_port (AST_Extended_Port *)
168 return 0;
172 ast_visitor_reifying::visit_mirror_port (AST_Mirror_Port *)
174 return 0;
178 ast_visitor_reifying::visit_connector (AST_Connector *node)
180 this->check_and_store (node);
181 return 0;
185 ast_visitor_reifying::visit_home (AST_Home *node)
187 this->check_and_store (node);
188 return 0;
192 ast_visitor_reifying::visit_factory (AST_Factory *)
194 return 0;
198 ast_visitor_reifying::visit_finder (AST_Finder *)
200 return 0;
204 ast_visitor_reifying::visit_structure (AST_Structure *node)
206 this->check_and_store (node);
207 return 0;
211 ast_visitor_reifying::visit_structure_fwd (AST_StructureFwd *)
213 return 0;
217 ast_visitor_reifying::visit_expression (AST_Expression *)
219 return 0;
223 ast_visitor_reifying::visit_enum (AST_Enum *node)
225 this->check_and_store (node);
226 return 0;
230 ast_visitor_reifying::visit_operation (AST_Operation *)
232 return 0;
236 ast_visitor_reifying::visit_field (AST_Field *)
238 return 0;
242 ast_visitor_reifying::visit_argument (AST_Argument *)
244 return 0;
248 ast_visitor_reifying::visit_attribute (AST_Attribute *)
250 return 0;
254 ast_visitor_reifying::visit_union (AST_Union *node)
256 this->check_and_store (node);
257 return 0;
261 ast_visitor_reifying::visit_union_fwd (AST_UnionFwd *)
263 return 0;
267 ast_visitor_reifying::visit_union_branch (AST_UnionBranch *)
269 return 0;
273 ast_visitor_reifying::visit_union_label (AST_UnionLabel *)
275 return 0;
279 ast_visitor_reifying::visit_enum_val (AST_EnumVal *)
281 return 0;
285 ast_visitor_reifying::visit_root (AST_Root *)
287 return 0;
291 ast_visitor_reifying::visit_native (AST_Native *node)
293 this->check_and_store (node);
294 return 0;
298 ast_visitor_reifying::visit_interface (AST_Interface *node)
300 this->check_and_store (node);
301 return 0;
305 ast_visitor_reifying::visit_valuetype (AST_ValueType *node)
307 this->check_and_store (node);
308 return 0;
312 ast_visitor_reifying::visit_eventtype (AST_EventType *node)
314 this->check_and_store (node);
315 return 0;
319 ast_visitor_reifying::visit_component (AST_Component *node)
321 this->check_and_store (node);
322 return 0;
326 ast_visitor_reifying::visit_exception (AST_Exception *node)
328 this->check_and_store (node);
329 return 0;
333 ast_visitor_reifying::visit_typedef (AST_Typedef *node)
335 this->check_and_store (node);
336 return 0;
340 ast_visitor_reifying::visit_array (AST_Array *node)
342 AST_Type *bt = node->base_type ();
344 if (bt->ast_accept (this) != 0)
346 ACE_ERROR_RETURN ((LM_ERROR,
347 ACE_TEXT ("ast_visitor_reifying::")
348 ACE_TEXT ("visit_array - ")
349 ACE_TEXT ("visit of base type failed\n")),
350 -1);
353 bt = dynamic_cast<AST_Type*> (this->reified_node_);
355 AST_Expression **dims = node->dims ();
356 AST_Expression *v = nullptr;
357 UTL_ExprList *v_list = nullptr;
359 for (ACE_CDR::ULong i = 0; i < node->n_dims (); ++i)
361 AST_Param_Holder *ph = dims[i]->param_holder ();
363 if (ph != nullptr)
365 if (this->visit_param_holder (ph) != 0)
367 if (v_list != nullptr)
369 v_list->destroy ();
370 delete v_list;
371 v_list = nullptr;
374 ACE_ERROR_RETURN ((LM_ERROR,
375 ACE_TEXT ("ast_visitor_reifying::")
376 ACE_TEXT ("visit_array - ")
377 ACE_TEXT ("visit_param_holder() ")
378 ACE_TEXT ("failed\n")),
379 -1);
382 AST_Constant *c = dynamic_cast<AST_Constant*> (this->reified_node_);
384 ACE_NEW_RETURN (v,
385 AST_Expression (c->constant_value (),
386 AST_Expression::EV_ulong),
387 -1);
389 else
391 ACE_NEW_RETURN (v,
392 AST_Expression (dims[i],
393 AST_Expression::EV_ulong),
394 -1);
397 UTL_ExprList *el = nullptr;
398 ACE_NEW_RETURN (el,
399 UTL_ExprList (v, nullptr),
400 -1);
402 if (v_list == nullptr)
404 v_list = el;
406 else
408 v_list->nconc (el);
412 UTL_ScopedName sn (node->local_name (), nullptr);
414 AST_Array *arr =
415 idl_global->gen ()->create_array (&sn,
416 node->n_dims (),
417 v_list,
418 false,
419 false);
421 // No need to add this new node to any scope - it's anonymous
422 // and owned by the node that references it.
424 if (v_list != nullptr)
426 v_list->destroy ();
427 delete v_list;
428 v_list = nullptr;
431 arr->set_base_type (bt);
432 this->reified_node_ = arr;
434 return 0;
438 ast_visitor_reifying::visit_sequence (AST_Sequence *node)
440 AST_Type *bt = node->base_type ();
442 if (bt->ast_accept (this) != 0)
444 ACE_ERROR_RETURN ((LM_ERROR,
445 ACE_TEXT ("ast_visitor_reifying::")
446 ACE_TEXT ("visit_sequence - ")
447 ACE_TEXT ("visit of base type failed\n")),
448 -1);
451 bt = dynamic_cast<AST_Type*> (this->reified_node_);
453 AST_Expression *v = node->max_size ();
454 AST_Param_Holder *ph = v->param_holder ();
456 if (ph != nullptr)
458 if (this->visit_param_holder (ph) != 0)
460 ACE_ERROR_RETURN ((LM_ERROR,
461 ACE_TEXT ("ast_visitor_reifying::")
462 ACE_TEXT ("visit_sequence - ")
463 ACE_TEXT ("visit_param_holder() ")
464 ACE_TEXT ("failed\n")),
465 -1);
468 AST_Constant *c = dynamic_cast<AST_Constant*> (this->reified_node_);
470 v = c->constant_value ();
473 AST_Expression *bound =
474 idl_global->gen ()->create_expr (v,
475 AST_Expression::EV_ulong);
476 Identifier id ("sequence");
477 UTL_ScopedName sn (&id, nullptr);
479 this->reified_node_ =
480 idl_global->gen ()->create_sequence (bound,
482 &sn,
483 false,
484 false);
486 // No need to add this new node to any scope - it's anonymous
487 // and owned by the node that references it.
489 return 0;
493 ast_visitor_reifying::visit_map (AST_Map *node)
495 AST_Type *key_bt = node->key_type ();
496 AST_Type *value_bt = node->value_type ();
498 if (key_bt->ast_accept (this) != 0)
500 ACE_ERROR_RETURN ((LM_ERROR,
501 ACE_TEXT ("ast_visitor_reifying::")
502 ACE_TEXT ("visit_map - ")
503 ACE_TEXT ("visit of key type failed\n")),
504 -1);
507 key_bt = dynamic_cast<AST_Type*> (this->reified_node_);
509 if (value_bt->ast_accept (this) != 0)
511 ACE_ERROR_RETURN ((LM_ERROR,
512 ACE_TEXT ("ast_visitor_reifying::")
513 ACE_TEXT ("visit_map - ")
514 ACE_TEXT ("visit of value type failed\n")),
515 -1);
518 value_bt = dynamic_cast<AST_Type*> (this->reified_node_);
520 AST_Expression *v = node->max_size ();
521 AST_Param_Holder *ph = v->param_holder ();
523 if (ph != nullptr)
525 if (this->visit_param_holder (ph) != 0)
527 ACE_ERROR_RETURN ((LM_ERROR,
528 ACE_TEXT ("ast_visitor_reifying::")
529 ACE_TEXT ("visit_map - ")
530 ACE_TEXT ("visit_param_holder() ")
531 ACE_TEXT ("failed\n")),
532 -1);
535 AST_Constant *c = dynamic_cast<AST_Constant*> (this->reified_node_);
537 v = c->constant_value ();
540 AST_Expression *bound =
541 idl_global->gen ()->create_expr (v,
542 AST_Expression::EV_ulong);
543 Identifier id ("map");
544 UTL_ScopedName sn (&id, nullptr);
546 this->reified_node_ =
547 idl_global->gen ()->create_map (bound,
548 key_bt,
549 value_bt,
550 &sn,
551 false,
552 false);
554 // No need to add this new node to any scope - it's anonymous
555 // and owned by the node that references it.
557 return 0;
561 ast_visitor_reifying::visit_predefined_type (AST_PredefinedType *node)
563 this->reified_node_ = node;
564 return 0;
568 ast_visitor_reifying::visit_string (AST_String *node)
570 AST_Expression *b = node->max_size ();
571 AST_Param_Holder *ph = b->param_holder ();
573 if (ph != nullptr)
575 if (this->visit_param_holder (ph) != 0)
577 ACE_ERROR_RETURN ((LM_ERROR,
578 ACE_TEXT ("ast_visitor_reifying::")
579 ACE_TEXT ("visit_string - ")
580 ACE_TEXT ("visit_param_holder() ")
581 ACE_TEXT ("failed\n")),
582 -1);
585 AST_Constant *c = dynamic_cast<AST_Constant*> (this->reified_node_);
587 b = c->constant_value ();
589 else if (b->ev ()->u.ulval == 0)
591 this->reified_node_ = node;
592 return 0;
595 AST_Expression *bound = nullptr;
596 ACE_NEW_RETURN (bound,
597 AST_Expression (b,
598 AST_Expression::EV_ulong),
599 -1);
601 Identifier id ("string");
602 UTL_ScopedName sn (&id, nullptr);
604 ACE_NEW_RETURN (this->reified_node_,
605 AST_String (AST_Decl::NT_string,
606 &sn,
607 bound,
608 node->width ()),
609 -1);
611 return 0;
615 ast_visitor_reifying::visit_constant (AST_Constant *node)
617 // AFAICT, this is called only on the member constant of a param
618 // holder, in which case nothing further is needed.
619 this->reified_node_ = node;
620 return 0;
624 ast_visitor_reifying::visit_param_holder (AST_Param_Holder *node)
626 size_t i = 0;
627 FE_Utils::T_ARGLIST const *t_args =
628 this->ctx_->template_args ();
630 for (FE_Utils::T_PARAMLIST_INFO::ITERATOR iter (
631 *this->ctx_->template_params ());
632 !iter.done ();
633 iter.advance (), ++i)
635 FE_Utils::T_Param_Info *item = nullptr;
636 iter.next (item);
638 ACE_CString name (item->name_);
640 /// The param holder's info->name_ may be the same as the
641 /// node's local name, but if the node comes from an
642 /// alias, info->name_ will be the name of the alias's
643 /// referenced template module parameter, while the local
644 /// name will be that of the corresponding alias param
645 /// name, which is what we want.
646 if (name == node->local_name ()->get_string ())
648 AST_Decl **ret_ptr = nullptr;
650 if (t_args->get (ret_ptr, i) == 0)
652 AST_Decl *candidate = *ret_ptr;
654 return candidate->ast_accept (this);
656 else
658 ACE_ERROR_RETURN ((LM_ERROR,
659 ACE_TEXT ("ast_visitor_reifying::")
660 ACE_TEXT ("visit_param_holder() - access of ")
661 ACE_TEXT ("current template arglist failed - ")
662 ACE_TEXT ("param=%C scope=%C index=%d\n"),
663 item->name_.c_str (),
664 ScopeAsDecl (idl_global->scopes ().top ())->full_name (),
666 -1);
671 ACE_ERROR_RETURN ((LM_ERROR,
672 ACE_TEXT ("ast_visitor_reifying::")
673 ACE_TEXT ("visit_param_holder() - no match for ")
674 ACE_TEXT ("template param %C in %C\n"),
675 node->local_name ()->get_string (),
676 ScopeAsDecl (idl_global->scopes ().top ())->full_name ()),
677 -1);
680 void
681 ast_visitor_reifying::check_and_store (AST_Decl *node)
683 UTL_ScopedName *tmpl_tail =
684 this->template_module_rel_name (node);
686 if (tmpl_tail != nullptr)
688 AST_Decl *d =
689 idl_global->scopes ().top ()->lookup_by_name (
690 tmpl_tail,
691 true,
692 false);
694 this->reified_node_ = d;
696 tmpl_tail->destroy ();
697 delete tmpl_tail;
698 tmpl_tail = nullptr;
700 else
702 this->reified_node_ = node;
706 UTL_ScopedName *
707 ast_visitor_reifying::template_module_rel_name (AST_Decl *d)
709 AST_Decl *tmp = d;
710 ACE_CString name (d->full_name ());
712 while (tmp != nullptr)
714 if (dynamic_cast<AST_Template_Module*> (tmp) != nullptr)
716 ACE_CString head (tmp->local_name ()->get_string ());
718 ACE_CString::size_type start = name.find (head) + 2;
720 ACE_CString tail (name.substr (start + head.length ()));
722 return FE_Utils::string_to_scoped_name (tail.c_str ());
725 tmp = ScopeAsDecl (tmp->defined_in ());
728 return nullptr;