Merge pull request #2301 from sonndinh/remove-dup-reactor-functions
[ACE_TAO.git] / TAO / orbsvcs / IFR_Service / ifr_adding_visitor.cpp
blob82757cb9f15b747469a1e2916b17e47d72f527ce
1 /* -*- c++ -*- */
2 #include "orbsvcs/Log_Macros.h"
3 #include "ast_argument.h"
4 #include "ast_array.h"
5 #include "ast_attribute.h"
6 #include "ast_component.h"
7 #include "ast_component_fwd.h"
8 #include "ast_provides.h"
9 #include "ast_uses.h"
10 #include "ast_publishes.h"
11 #include "ast_emits.h"
12 #include "ast_consumes.h"
13 #include "ast_constant.h"
14 #include "ast_enum.h"
15 #include "ast_eventtype.h"
16 #include "ast_eventtype_fwd.h"
17 #include "ast_exception.h"
18 #include "ast_expression.h"
19 #include "ast_finder.h"
20 #include "ast_field.h"
21 #include "ast_home.h"
22 #include "ast_interface.h"
23 #include "ast_interface_fwd.h"
24 #include "ast_module.h"
25 #include "ast_native.h"
26 #include "ast_operation.h"
27 #include "ast_predefined_type.h"
28 #include "ast_root.h"
29 #include "ast_sequence.h"
30 #include "ast_string.h"
31 #include "ast_structure.h"
32 #include "ast_typedef.h"
33 #include "ast_union.h"
34 #include "ast_union_fwd.h"
35 #include "ast_valuebox.h"
36 #include "ast_valuetype.h"
37 #include "ast_valuetype_fwd.h"
38 #include "utl_identifier.h"
39 #include "utl_string.h"
40 #include "utl_exceptlist.h"
41 #include "fe_extern.h"
42 #include "nr_extern.h"
44 #include "ifr_adding_visitor.h"
45 #include "ifr_adding_visitor_operation.h"
46 #include "ifr_adding_visitor_structure.h"
47 #include "ifr_adding_visitor_exception.h"
48 #include "ifr_adding_visitor_union.h"
50 #include "tao/IFR_Client/IFR_ComponentsC.h"
52 #include "ace/Vector_T.h"
54 ifr_adding_visitor::ifr_adding_visitor (
55 AST_Decl *scope,
56 bool in_reopened,
57 bool allow_duplicate_typedefs)
58 : scope_ (scope),
59 in_reopened_ (in_reopened),
60 allow_duplicate_typedefs_ (allow_duplicate_typedefs)
64 ifr_adding_visitor::~ifr_adding_visitor ()
68 int
69 ifr_adding_visitor::visit_scope (UTL_Scope *node)
71 // Proceed if the number of members in our scope is greater than 0.
72 if (node->nmembers () > 0)
74 // Initialize an iterator to iterate over our scope.
75 UTL_ScopeActiveIterator si (node,
76 UTL_Scope::IK_decls);
78 AST_Decl *d = 0;
80 // Continue until each element is visited.
81 while (!si.is_done ())
83 d = si.item ();
85 if (d == 0)
87 ORBSVCS_ERROR_RETURN ((
88 LM_ERROR,
89 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_scope -")
90 ACE_TEXT (" bad node in this scope\n")),
95 // These are created at startup in the repository, and
96 // need not be dealt with here.
97 if (d->node_type () == AST_Decl::NT_pre_defined)
99 si.next ();
100 continue;
103 if (d->ast_accept (this) == -1)
105 ORBSVCS_ERROR_RETURN ((
106 LM_ERROR,
107 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_scope -")
108 ACE_TEXT (" failed to accept visitor\n")),
113 si.next ();
117 return 0;
121 ifr_adding_visitor::visit_predefined_type (AST_PredefinedType *node)
125 this->ir_current_ =
126 be_global->repository ()->get_primitive (this->predefined_type_to_pkind (node));
128 catch (const CORBA::Exception& ex)
130 ex._tao_print_exception (ACE_TEXT ("visit_predefined_type"));
132 return -1;
135 return 0;
139 ifr_adding_visitor::visit_module (AST_Module *node)
141 if (node->imported () && !be_global->do_included_files ())
143 return 0;
146 CORBA::Container_var new_def;
150 // If this module been opened before, it will already be in
151 // the repository.
152 CORBA::Contained_var prev_def =
153 be_global->repository ()->lookup_id (node->repoID ());
155 if (CORBA::is_nil (prev_def.in ()))
157 // New module.
158 CORBA::Container_ptr container =
159 CORBA::Container::_nil ();
161 if (be_global->ifr_scopes ().top (container) == 0)
163 new_def = container->create_module (
164 node->repoID (),
165 node->local_name ()->get_string (),
166 node->version ()
169 else
171 ORBSVCS_ERROR_RETURN ((
172 LM_ERROR,
173 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_module -")
174 ACE_TEXT (" scope stack is empty\n")
180 else
182 CORBA::DefinitionKind kind =
183 prev_def->def_kind ();
185 if (kind == CORBA::dk_Module)
187 // We are either in a reopened module, are processing an IDL
188 // IDL file for the second time, or are in a module whose
189 // name already exists by coincidence - there is no way to
190 // tell the difference. So any members whose repository ID
191 // already exists in this case will throw BAD_PARAM
192 // when we attempt to add them to the repository.
193 this->in_reopened_ = true;
195 new_def =
196 CORBA::ComponentIR::Container::_narrow (prev_def.in ());
200 if (be_global->ifr_scopes ().push (new_def.in ()) != 0)
202 ORBSVCS_ERROR_RETURN ((
203 LM_ERROR,
204 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_module -")
205 ACE_TEXT (" scope push failed\n")
211 if (this->visit_scope (node) == -1)
213 ORBSVCS_ERROR_RETURN ((
214 LM_ERROR,
215 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_module -")
216 ACE_TEXT (" visit_scope failed\n")
222 this->in_reopened_ = false;
223 CORBA::Container_ptr tmp =
224 CORBA::Container::_nil ();
226 if (be_global->ifr_scopes ().pop (tmp) != 0)
228 ORBSVCS_ERROR_RETURN ((
229 LM_ERROR,
230 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_module -")
231 ACE_TEXT (" scope pop failed\n")
237 catch (const CORBA::Exception& ex)
239 ex._tao_print_exception (ACE_TEXT ("visit_module"));
241 return -1;
244 return 0;
248 ifr_adding_visitor::visit_interface (AST_Interface *node)
250 if (node->imported () && !be_global->do_included_files ())
252 return 0;
257 // Is this interface already in the respository?
258 CORBA::Contained_var prev_def =
259 be_global->repository ()->lookup_id (node->repoID ());
261 // If not, create a new entry.
262 if (CORBA::is_nil (prev_def.in ()))
264 int status = this->create_interface_def (node);
266 return status;
268 else
270 // There is already an entry in the repository. If the interface is
271 // defined and has not already been populated, we do so
272 // now. If it is not yet defined or the full definition has already
273 // been added to the repository, we just update the current IR object
274 // holder.
275 if (node->is_defined () && !node->ifr_added ())
277 // If we are here and the line below is true, then either
278 // 1. We are defining an undefined forward declaration
279 // from a previously processed IDL file, or
280 // 2. We are clobbering a previous definition, either of the
281 // node type or of some other type.
282 // If prev_def would narrow successfully to the node type, we
283 // have NO WAY of knowing if we are defining or clobbering. So
284 // we destroy the contents of the previous entry (we don't want
285 // to destroy the entry itself, since it may have already been
286 // made a member of some other entry, and destroying it would
287 // make the containing entry's section key invalid) and repopulate.
288 // On the other hand, if prev_def is NOT the node type, we go
289 // ahead an attempt to create an interface, which will get an
290 // exception from the IFR, as the spec requires.
291 if (!node->ifr_fwd_added () && !node->imported ())
293 CORBA::DefinitionKind kind = prev_def->def_kind ();
295 if (kind == CORBA::dk_Interface)
297 CORBA::InterfaceDef_var iface =
298 CORBA::InterfaceDef::_narrow (prev_def.in ());
300 CORBA::ContainedSeq_var contents =
301 iface->contents (CORBA::dk_all, true);
303 for (CORBA::ULong i = 0; i < contents->length (); ++i)
305 contents[i]->destroy ();
308 else
310 // This will cause the IFR to throw an exception,
311 // as it should.
312 return this->create_interface_def (node);
316 CORBA::ULong n_parents = static_cast<CORBA::ULong> (node->n_inherits ());
318 CORBA::InterfaceDefSeq bases (n_parents);
319 bases.length (n_parents);
320 CORBA::Contained_var result;
322 AST_Type **parents = node->inherits ();
324 // Construct a list of the parents.
325 for (CORBA::ULong i = 0; i < n_parents; ++i)
327 result =
328 be_global->repository ()->lookup_id (parents[i]->repoID ());
330 // If one of our interface's parents is not in the repository,
331 // that means that it has not yet been seen (even as a
332 // forward declaration) in the IDL file, and we will have to
333 // postpone the populating of our interface until they are all
334 // added.
335 if (CORBA::is_nil (result.in ()))
337 this->ir_current_ =
338 CORBA::IDLType::_narrow (prev_def.in ());
340 return 0;
343 bases[i] =
344 CORBA::InterfaceDef::_narrow (result.in ());
346 if (CORBA::is_nil (bases[i]))
348 ORBSVCS_ERROR_RETURN ((
349 LM_ERROR,
350 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
351 ACE_TEXT ("visit_interface -")
352 ACE_TEXT (" CORBA::InterfaceDef::_narrow failed\n")
359 CORBA::InterfaceDef_var extant_def =
360 CORBA::InterfaceDef::_narrow (prev_def. in ());
362 extant_def->base_interfaces (bases);
364 node->ifr_added (true);
366 // Push the new IR object onto the scope stack.
367 if (be_global->ifr_scopes ().push (extant_def.in ()) != 0)
369 ORBSVCS_ERROR_RETURN ((
370 LM_ERROR,
371 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
372 ACE_TEXT ("visit_interface -")
373 ACE_TEXT (" scope push failed\n")
379 // Visit the members, if any.
380 if (this->visit_scope (node) == -1)
382 ORBSVCS_ERROR_RETURN ((
383 LM_ERROR,
384 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
385 ACE_TEXT ("visit_interface -")
386 ACE_TEXT (" visit_scope failed\n")
392 // This spot in the AST doesn't necessarily have to be the
393 // interface definition - it could be any reference to it.
394 // The front end will already have fully defined it, so all
395 // the info is available anywhere. So it's a good idea to
396 // update the current IR object holder now.
397 this->ir_current_ =
398 CORBA::IDLType::_duplicate (extant_def.in ());
400 CORBA::Container_ptr used_scope =
401 CORBA::Container::_nil ();
403 // Pop the new IR object back off the scope stack.
404 if (be_global->ifr_scopes ().pop (used_scope) != 0)
406 ORBSVCS_ERROR_RETURN ((
407 LM_ERROR,
408 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
409 ACE_TEXT ("visit_interface -")
410 ACE_TEXT (" scope pop failed\n")
416 else
418 // @@ (JP) I think we're ok here without a check:
419 // not defined/not added - visit_interface_fwd will have
420 // detected a clobber.
421 // not defined/added - not possible.
422 // defined/not added - takes the other branch.
423 // defined/added - we're ok.
424 this->ir_current_ =
425 CORBA::IDLType::_narrow (prev_def.in ());
429 catch (const CORBA::Exception& ex)
431 ex._tao_print_exception (ACE_TEXT ("visit_interface"));
433 return -1;
436 return 0;
440 ifr_adding_visitor::visit_interface_fwd (AST_InterfaceFwd *node)
442 if (node->imported () && !be_global->do_included_files ())
444 return 0;
447 AST_Interface *i = node->full_definition ();
451 // Is this interface already in the respository?
452 CORBA::Contained_var prev_def =
453 be_global->repository ()->lookup_id (i->repoID ());
455 if (CORBA::is_nil (prev_def.in ()))
457 // If our full definition is found in this IDL file, we go
458 // ahead and create the full entry now.
459 // The forward declared interface is not defined anywhere
460 // in this IDL file, so we just create an empty entry to
461 // be replaced by a full definition in some other IDL file.
462 CORBA::InterfaceDefSeq bases (0);
463 bases.length (0);
465 CORBA::Container_ptr current_scope =
466 CORBA::Container::_nil ();
468 if (be_global->ifr_scopes ().top (current_scope) == 0)
470 if (i->is_local ())
472 this->ir_current_ =
473 current_scope->create_local_interface (
474 i->repoID (),
475 i->local_name ()->get_string (),
476 i->version (),
477 bases
480 else
482 this->ir_current_ =
483 current_scope->create_interface (
484 i->repoID (),
485 i->local_name ()->get_string (),
486 i->version (),
487 bases
492 else
494 ORBSVCS_ERROR_RETURN ((
495 LM_ERROR,
496 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
497 ACE_TEXT ("visit_interface_fwd -")
498 ACE_TEXT (" scope stack is empty\n")
504 node->ifr_added (true);
505 i->ifr_fwd_added (true);
509 catch (const CORBA::Exception& ex)
511 ex._tao_print_exception (ACE_TEXT ("visit_interface_fwd"));
513 return -1;
516 return 0;
520 ifr_adding_visitor::visit_valuebox (AST_ValueBox *node)
522 if (node->imported () && !be_global->do_included_files ())
524 return 0;
529 this->element_type (node->boxed_type ());
531 CORBA::Container_ptr current_scope =
532 CORBA::Container::_nil ();
534 if (be_global->ifr_scopes ().top (current_scope) == 0)
536 this->ir_current_ =
537 current_scope->create_value_box (
538 node->repoID (),
539 node->local_name ()->get_string (),
540 node->version (),
541 this->ir_current_.in ()
544 else
546 ORBSVCS_ERROR_RETURN ((
547 LM_ERROR,
548 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_valuebox -")
549 ACE_TEXT (" scope stack is empty\n")
555 node->ifr_added (true);
557 catch (const CORBA::Exception& ex)
559 ex._tao_print_exception (ACE_TEXT ("visit_valuebox"));
561 return -1;
564 return 0;
568 ifr_adding_visitor::visit_valuetype (AST_ValueType *node)
570 if (node->imported () && !be_global->do_included_files ())
572 return 0;
577 // Is this valuetype already in the respository?
578 CORBA::Contained_var prev_def =
579 be_global->repository ()->lookup_id (node->repoID ());
581 // If not, create a new entry.
582 if (CORBA::is_nil (prev_def.in ()))
584 int status = this->create_value_def (node);
586 return status;
588 else
590 // There is already an entry in the repository. If the interface is
591 // defined and has not already been populated, we do so
592 // now. If it is not yet defined or the full definition has already
593 // been added to the repository, we just update the current IR object
594 // holder.
595 if (node->is_defined () && !node->ifr_added ())
597 // If we are here and the line below is true, then either
598 // 1. We are defining an undefined forward declaration
599 // from a previously processed IDL file, or
600 // 2. We are clobbering a previous definition, either of the
601 // node type or of some other type.
602 // If prev_def would narrow successfully to the node type, we
603 // have NO WAY of knowing if we are defining or clobbering. So
604 // we destroy the contents of the previous entry (we don't want
605 // to destroy the entry itself, since it may have already been
606 // made a member of some other entry, and destroying it would
607 // make the containing entry's section key invalid) and repopulate.
608 // On the other hand, if prev_def is NOT the node type, we go
609 // ahead an attempt to create an interface, which will get an
610 // exception from the IFR, as the spec requires.
611 if (!node->ifr_fwd_added ())
613 CORBA::DefinitionKind kind =
614 prev_def->def_kind ();
616 if (kind == CORBA::dk_Value)
618 CORBA::ValueDef_var value =
619 CORBA::ValueDef::_narrow (prev_def.in ());
621 CORBA::ContainedSeq_var contents =
622 value->contents (CORBA::dk_all,
625 CORBA::ULong length = contents->length ();
627 for (CORBA::ULong i = 0; i < length; ++i)
629 contents[i]->destroy ();
632 else
634 prev_def->destroy ();
636 int status =
637 this->create_value_def (node);
639 return status;
643 // Our previous definition is a valuetype, so narrow it here,
644 // then populate it.
645 CORBA::ExtValueDef_var extant_def =
646 CORBA::ExtValueDef::_narrow (prev_def. in ());
648 // Concrete base value.
650 CORBA::ValueDef_var base_vt;
651 this->fill_base_value (base_vt.out (),
652 node);
654 extant_def->base_value (base_vt.in ());
656 // Abstract base values.
658 CORBA::ValueDefSeq abstract_base_values;
659 this->fill_abstract_base_values (abstract_base_values,
660 node);
662 extant_def->abstract_base_values (abstract_base_values);
664 // Supported interfaces.
666 CORBA::InterfaceDefSeq supported;
667 this->fill_supported_interfaces (supported,
668 node);
670 extant_def->supported_interfaces (supported);
672 // Intializers.
674 CORBA::ExtInitializerSeq initializers;
675 this->fill_initializers (initializers,
676 node);
678 extant_def->ext_initializers (initializers);
680 // Truncatable, abstract, custom.
682 extant_def->is_abstract (static_cast<CORBA::Boolean> (node->is_abstract ()));
684 extant_def->is_truncatable (static_cast<CORBA::Boolean> (node->truncatable ()));
686 extant_def->is_custom (static_cast<CORBA::Boolean> (node->custom ()));
688 node->ifr_added (true);
690 // Push the new IR object onto the scope stack before visiting
691 // the new object's scope.
692 if (be_global->ifr_scopes ().push (extant_def.in ()) != 0)
694 ORBSVCS_ERROR_RETURN ((
695 LM_ERROR,
696 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
697 ACE_TEXT ("visit_valuetype -")
698 ACE_TEXT (" scope push failed\n")
704 // Visit the members, if any.
705 if (this->visit_scope (node) == -1)
707 ORBSVCS_ERROR_RETURN ((
708 LM_ERROR,
709 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
710 ACE_TEXT ("visit_valuetype -")
711 ACE_TEXT (" visit_scope failed\n")
717 // This spot in the AST doesn't necessarily have to be the
718 // interface definition - it could be any reference to it.
719 // The front end will already have fully defined it, so all
720 // the info is available anywhere. So it's a good idea to
721 // update the current IR object holder now.
722 this->ir_current_ =
723 CORBA::IDLType::_duplicate (extant_def.in ());
725 CORBA::Container_ptr used_scope =
726 CORBA::Container::_nil ();
728 // Pop the new IR object back off the scope stack.
729 if (be_global->ifr_scopes ().pop (used_scope) != 0)
731 ORBSVCS_ERROR_RETURN ((
732 LM_ERROR,
733 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
734 ACE_TEXT ("visit_valuetype -")
735 ACE_TEXT (" scope pop failed\n")
741 else
743 // @@ (JP) I think we're ok here without a check:
744 // not defined/not added - visit_valuetype_fwd will have
745 // detected a clobber.
746 // not defined/added - not possible.
747 // defined/not added - takes the other branch.
748 // defined/added - we're ok.
749 this->ir_current_ =
750 CORBA::IDLType::_narrow (prev_def.in ());
754 catch (const CORBA::Exception& ex)
756 ex._tao_print_exception (ACE_TEXT ("visit_valuetype"));
758 return -1;
761 return 0;
765 ifr_adding_visitor::visit_valuetype_fwd (AST_ValueTypeFwd *node)
767 if (node->imported () && !be_global->do_included_files ())
769 return 0;
772 AST_Interface *v = node->full_definition ();
776 // Is this interface already in the respository?
777 CORBA::Contained_var prev_def =
778 be_global->repository ()->lookup_id (v->repoID ());
780 if (CORBA::is_nil (prev_def.in ()))
782 // If our full definition is found in this IDL file, we go
783 // ahead and create the full entry now.
784 // The forward declared valuetype is not defined anywhere
785 // in this IDL file, so we just create an empty entry to
786 // be replaced by a full definition in some other IDL file.
787 CORBA::ValueDefSeq abstract_bases (0);
788 abstract_bases.length (0);
789 CORBA::InterfaceDefSeq supported (0);
790 supported.length (0);
791 CORBA::InitializerSeq initializers (0);
792 initializers.length (0);
794 CORBA::Container_ptr current_scope =
795 CORBA::Container::_nil ();
797 CORBA::Boolean abstract =
798 static_cast<CORBA::Boolean> (v->is_abstract ());
800 if (be_global->ifr_scopes ().top (current_scope) == 0)
802 this->ir_current_ =
803 current_scope->create_value (
804 v->repoID (),
805 v->local_name ()->get_string (),
806 v->version (),
807 0, // 'custom' not handled yet
808 abstract,
809 CORBA::ValueDef::_nil (),
810 0, // 'truncatable' not handled yet
811 abstract_bases,
812 supported,
813 initializers
816 else
818 ORBSVCS_ERROR_RETURN ((
819 LM_ERROR,
820 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
821 ACE_TEXT ("visit_valuetype_fwd -")
822 ACE_TEXT (" scope stack is empty\n")
828 node->ifr_added (true);
829 v->ifr_fwd_added (true);
832 catch (const CORBA::Exception& ex)
834 ex._tao_print_exception (ACE_TEXT ("visit_valuetype_fwd"));
836 return -1;
839 return 0;
843 ifr_adding_visitor::visit_component (AST_Component *node)
845 if (node->imported () && !be_global->do_included_files ())
847 return 0;
852 // Is this interface already in the respository?
853 CORBA::Contained_var prev_def =
854 be_global->repository ()->lookup_id (node->repoID ());
856 // If not, create a new entry.
857 if (CORBA::is_nil (prev_def.in ()))
859 int status = this->create_component_def (node);
861 return status;
863 else
865 // There is already an entry in the repository. If the interface is
866 // defined and has not already been populated, we do so
867 // now. If it is not yet defined or the full definition has already
868 // been added to the repository, we just update the current IR object
869 // holder.
870 if (node->is_defined () && !node->ifr_added ())
872 // If we are here and the line below is true, then either
873 // 1. We are defining an undefined forward declaration
874 // from a previously processed IDL file, or
875 // 2. We are clobbering a previous definition, either of the
876 // node type or of some other type.
877 // If prev_def would narrow successfully to the node type, we
878 // have NO WAY of knowing if we are defining or clobbering. So
879 // we destroy the contents of the previous entry (we don't want
880 // to destroy the entry itself, since it may have already been
881 // made a member of some other entry, and destroying it would
882 // make the containing entry's section key invalid) and repopulate.
883 // On the other hand, if prev_def is NOT the node type, we go
884 // ahead an attempt to create an interface, which will get an
885 // exception from the IFR, as the spec requires.
886 if (!node->ifr_fwd_added ())
888 CORBA::DefinitionKind kind =
889 prev_def->def_kind ();
891 if (kind == CORBA::dk_Component)
893 CORBA::ComponentIR::ComponentDef_var value =
894 CORBA::ComponentIR::ComponentDef::_narrow (
895 prev_def.in ()
898 CORBA::ContainedSeq_var contents =
899 value->contents (CORBA::dk_all,
902 CORBA::ULong length = contents->length ();
904 for (CORBA::ULong i = 0; i < length; ++i)
906 contents[i]->destroy ();
909 else
911 prev_def->destroy ();
913 int status =
914 this->create_component_def (node);
916 return status;
920 // Re-populate the repository entry.
922 CORBA::ComponentIR::ComponentDef_var extant_def =
923 CORBA::ComponentIR::ComponentDef::_narrow (
924 prev_def.in ()
927 CORBA::InterfaceDefSeq supported_interfaces;
928 this->fill_supported_interfaces (supported_interfaces,
929 node);
931 extant_def->supported_interfaces (supported_interfaces);
933 CORBA::ComponentIR::ComponentDef_var base_component;
934 this->fill_base_component (base_component.out (),
935 node);
937 extant_def->base_component (base_component.in ());
939 node->ifr_added (true);
941 // Push the new IR object onto the scope stack before visiting
942 // the new object's scope.
943 if (be_global->ifr_scopes ().push (extant_def.in ()) != 0)
945 ORBSVCS_ERROR_RETURN ((
946 LM_ERROR,
947 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
948 ACE_TEXT ("visit_component -")
949 ACE_TEXT (" scope push failed\n")
955 // This spot in the AST doesn't necessarily have to be the
956 // interface definition - it could be any reference to it.
957 // The front end will already have fully defined it, so all
958 // the info is available anywhere. So it's a good idea to
959 // update the current IR object holder now.
960 this->ir_current_ =
961 CORBA::IDLType::_duplicate (extant_def.in ());
963 // Visit the members, if any.
964 if (this->visit_scope (node) == -1)
966 ORBSVCS_ERROR_RETURN ((
967 LM_ERROR,
968 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
969 ACE_TEXT ("visit_component -")
970 ACE_TEXT (" visit_scope failed\n")
976 CORBA::Container_ptr used_scope =
977 CORBA::Container::_nil ();
979 // Pop the new IR object back off the scope stack.
980 if (be_global->ifr_scopes ().pop (used_scope) != 0)
982 ORBSVCS_ERROR_RETURN ((
983 LM_ERROR,
984 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
985 ACE_TEXT ("visit_interface -")
986 ACE_TEXT (" scope pop failed\n")
992 else
994 // @@ (JP) I think we're ok here without a check:
995 // not defined/not added - visit_interface_fwd will have
996 // detected a clobber.
997 // not defined/added - not possible.
998 // defined/not added - takes the other branch.
999 // defined/added - we're ok.
1000 this->ir_current_ =
1001 CORBA::IDLType::_narrow (prev_def.in ());
1005 catch (const CORBA::Exception& ex)
1007 ex._tao_print_exception (ACE_TEXT ("visit_component"));
1009 return -1;
1012 return 0;
1016 ifr_adding_visitor::visit_component_fwd (AST_ComponentFwd *node)
1018 if (node->imported () && !be_global->do_included_files ())
1020 return 0;
1023 AST_Component *c =
1024 dynamic_cast<AST_Component*> (node->full_definition ());
1028 // Is this interface already in the respository?
1029 CORBA::Contained_var prev_def =
1030 be_global->repository ()->lookup_id (c->repoID ());
1032 if (CORBA::is_nil (prev_def.in ()))
1034 CORBA::Container_ptr current_scope =
1035 CORBA::Container::_nil ();
1037 if (be_global->ifr_scopes ().top (current_scope) == 0)
1039 CORBA::ComponentIR::Container_var ccm_scope =
1040 CORBA::ComponentIR::Container::_narrow (
1041 current_scope
1044 // If our full definition is found in this IDL file, we go
1045 // ahead and create the full entry now.
1046 // The forward declared component is not defined anywhere
1047 // in this IDL file, so we just create an empty entry to
1048 // be replaced by a full definition later.
1049 CORBA::InterfaceDefSeq supported_interfaces;
1050 supported_interfaces.length (0);
1051 CORBA::ComponentIR::ComponentDef_var base_component;
1054 if (node->is_defined ())
1056 this->fill_supported_interfaces (supported_interfaces,
1059 this->fill_base_component (base_component.out (),
1063 this->ir_current_ =
1064 ccm_scope->create_component (
1065 c->repoID (),
1066 c->local_name ()->get_string (),
1067 c->version (),
1068 base_component.in (),
1069 supported_interfaces
1072 else
1074 ORBSVCS_ERROR_RETURN ((
1075 LM_ERROR,
1076 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
1077 ACE_TEXT ("visit_component_fwd -")
1078 ACE_TEXT (" scope stack is empty\n")
1084 node->ifr_added (true);
1085 c->ifr_fwd_added (true);
1088 catch (const CORBA::Exception& ex)
1090 ex._tao_print_exception (ACE_TEXT ("visit_component_fwd"));
1092 return -1;
1095 return 0;
1099 ifr_adding_visitor::visit_provides (AST_Provides *node)
1101 ::CORBA::Contained_var contained =
1102 be_global->repository ()->lookup_id (
1103 node->provides_type ()->repoID ());
1105 ::CORBA::InterfaceDef_var interface_type =
1106 ::CORBA::InterfaceDef::_narrow (contained.in ());
1108 ::CORBA::ComponentIR::ComponentDef_var c =
1109 ::CORBA::ComponentIR::ComponentDef::_narrow (
1110 this->ir_current_.in ());
1112 ACE_CString comp_str (c->_interface_repository_id ());
1113 char *local_name = node->local_name ()->get_string ();
1114 this->expand_id (comp_str, local_name);
1116 ::CORBA::ComponentIR::ProvidesDef_var new_def =
1117 c->create_provides (comp_str.fast_rep (),
1118 local_name,
1119 node->provides_type ()->version (),
1120 interface_type.in ());
1122 return 0;
1126 ifr_adding_visitor::visit_uses (AST_Uses *node)
1128 ::CORBA::Contained_var contained =
1129 be_global->repository ()->lookup_id (
1130 node->uses_type ()->repoID ());
1132 ::CORBA::InterfaceDef_var interface_type =
1133 ::CORBA::InterfaceDef::_narrow (contained.in ());
1135 ::CORBA::ComponentIR::ComponentDef_var c =
1136 ::CORBA::ComponentIR::ComponentDef::_narrow (
1137 this->ir_current_.in ());
1139 ACE_CString comp_str (c->_interface_repository_id ());
1140 char *local_name = node->local_name ()->get_string ();
1141 this->expand_id (comp_str, local_name);
1143 ::CORBA::ComponentIR::UsesDef_var new_def =
1144 c->create_uses (comp_str.fast_rep (),
1145 local_name,
1146 node->uses_type ()->version (),
1147 interface_type.in (),
1148 static_cast<CORBA::Boolean> (node->is_multiple ()));
1150 return 0;
1154 ifr_adding_visitor::visit_publishes (AST_Publishes *node)
1156 ::CORBA::Contained_var contained =
1157 be_global->repository ()->lookup_id (
1158 node->publishes_type ()->repoID ());
1160 ::CORBA::ComponentIR::EventDef_var event_type =
1161 ::CORBA::ComponentIR::EventDef::_narrow (contained.in ());
1163 ::CORBA::ComponentIR::ComponentDef_var c =
1164 ::CORBA::ComponentIR::ComponentDef::_narrow (
1165 this->ir_current_.in ());
1167 ACE_CString comp_str (c->_interface_repository_id ());
1168 char *local_name = node->local_name ()->get_string ();
1169 this->expand_id (comp_str, local_name);
1171 ::CORBA::ComponentIR::PublishesDef_var new_def =
1172 c->create_publishes (comp_str.fast_rep (),
1173 local_name,
1174 node->publishes_type ()->version (),
1175 event_type.in ());
1177 return 0;
1181 ifr_adding_visitor::visit_emits (AST_Emits *node)
1183 ::CORBA::Contained_var contained =
1184 be_global->repository ()->lookup_id (
1185 node->emits_type ()->repoID ());
1187 ::CORBA::ComponentIR::EventDef_var event_type =
1188 ::CORBA::ComponentIR::EventDef::_narrow (contained.in ());
1190 ::CORBA::ComponentIR::ComponentDef_var c =
1191 ::CORBA::ComponentIR::ComponentDef::_narrow (
1192 this->ir_current_.in ());
1194 ACE_CString comp_str (c->_interface_repository_id ());
1195 char *local_name = node->local_name ()->get_string ();
1196 this->expand_id (comp_str, local_name);
1198 ::CORBA::ComponentIR::EmitsDef_var new_def =
1199 c->create_emits (comp_str.fast_rep (),
1200 local_name,
1201 node->emits_type ()->version (),
1202 event_type.in ());
1204 return 0;
1208 ifr_adding_visitor::visit_consumes (AST_Consumes *node)
1210 ::CORBA::Contained_var contained =
1211 be_global->repository ()->lookup_id (
1212 node->consumes_type ()->repoID ());
1214 ::CORBA::ComponentIR::EventDef_var event_type =
1215 ::CORBA::ComponentIR::EventDef::_narrow (contained.in ());
1217 ::CORBA::ComponentIR::ComponentDef_var c =
1218 ::CORBA::ComponentIR::ComponentDef::_narrow (
1219 this->ir_current_.in ());
1221 ACE_CString comp_str (c->_interface_repository_id ());
1222 char *local_name = node->local_name ()->get_string ();
1223 this->expand_id (comp_str, local_name);
1225 ::CORBA::ComponentIR::ConsumesDef_var new_def =
1226 c->create_consumes (comp_str.fast_rep (),
1227 local_name,
1228 node->consumes_type ()->version (),
1229 event_type.in ());
1231 return 0;
1235 ifr_adding_visitor::visit_eventtype (AST_EventType *node)
1237 if (node->imported () && !be_global->do_included_files ())
1239 return 0;
1244 // Is this interface already in the respository?
1245 CORBA::Contained_var prev_def =
1246 be_global->repository ()->lookup_id (node->repoID ());
1248 // If not, create a new entry.
1249 if (CORBA::is_nil (prev_def.in ()))
1251 int status = this->create_event_def (node);
1253 return status;
1255 else
1257 // There is already an entry in the repository. If the interface is
1258 // defined and has not already been populated, we do so
1259 // now. If it is not yet defined or the full definition has already
1260 // been added to the repository, we just update the current IR object
1261 // holder.
1262 if (node->is_defined () && !node->ifr_added ())
1264 // If we are here and the line below is true, then either
1265 // 1. We are defining an undefined forward declaration
1266 // from a previously processed IDL file, or
1267 // 2. We are clobbering a previous definition, either of the
1268 // node type or of some other type.
1269 // If prev_def would narrow successfully to the node type, we
1270 // have NO WAY of knowing if we are defining or clobbering. So
1271 // we destroy the contents of the previous entry (we don't want
1272 // to destroy the entry itself, since it may have already been
1273 // made a member of some other entry, and destroying it would
1274 // make the containing entry's section key invalid) and repopulate.
1275 // On the other hand, if prev_def is NOT the node type, we go
1276 // ahead an attempt to create an interface, which will get an
1277 // exception from the IFR, as the spec requires.
1278 if (!node->ifr_fwd_added ())
1280 CORBA::DefinitionKind kind =
1281 prev_def->def_kind ();
1283 if (kind == CORBA::dk_Value)
1285 CORBA::ComponentIR::EventDef_var event =
1286 CORBA::ComponentIR::EventDef::_narrow (
1287 prev_def.in ()
1290 CORBA::ContainedSeq_var contents =
1291 event->contents (CORBA::dk_all,
1294 CORBA::ULong length = contents->length ();
1296 for (CORBA::ULong i = 0; i < length; ++i)
1298 contents[i]->destroy ();
1301 else
1303 prev_def->destroy ();
1305 int status =
1306 this->create_event_def (node);
1308 return status;
1312 // Our previous definition is a valuetype, so narrow it here,
1313 // then populate it.
1314 CORBA::ComponentIR::EventDef_var extant_def =
1315 CORBA::ComponentIR::EventDef::_narrow (prev_def. in ());
1317 // Concrete base value.
1319 CORBA::ValueDef_var base_vt;
1320 this->fill_base_value (base_vt.out (),
1321 node);
1323 extant_def->base_value (base_vt.in ());
1325 // Abstract base values.
1327 CORBA::ValueDefSeq abstract_base_values;
1328 this->fill_abstract_base_values (abstract_base_values,
1329 node);
1331 extant_def->abstract_base_values (abstract_base_values);
1333 // Supported interfaces.
1335 CORBA::InterfaceDefSeq supported;
1336 this->fill_supported_interfaces (supported,
1337 node);
1339 extant_def->supported_interfaces (supported);
1341 // Intializers.
1343 CORBA::ExtInitializerSeq initializers;
1344 this->fill_initializers (initializers,
1345 node);
1347 extant_def->ext_initializers (initializers);
1349 // Truncatable, abstract, custom.
1351 extant_def->is_abstract (static_cast<CORBA::Boolean> (node->is_abstract ()));
1353 extant_def->is_truncatable (static_cast<CORBA::Boolean> (node->truncatable ()));
1355 extant_def->is_custom (static_cast<CORBA::Boolean> (node->custom ()));
1357 node->ifr_added (true);
1359 // Push the new IR object onto the scope stack before visiting
1360 // the new object's scope.
1361 if (be_global->ifr_scopes ().push (extant_def.in ()) != 0)
1363 ORBSVCS_ERROR_RETURN ((
1364 LM_ERROR,
1365 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
1366 ACE_TEXT ("visit_eventtype -")
1367 ACE_TEXT (" scope push failed\n")
1373 // Visit the members, if any.
1374 if (this->visit_scope (node) == -1)
1376 ORBSVCS_ERROR_RETURN ((
1377 LM_ERROR,
1378 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
1379 ACE_TEXT ("visit_eventtype -")
1380 ACE_TEXT (" visit_scope failed\n")
1386 // This spot in the AST doesn't necessarily have to be the
1387 // interface definition - it could be any reference to it.
1388 // The front end will already have fully defined it, so all
1389 // the info is available anywhere. So it's a good idea to
1390 // update the current IR object holder now.
1391 this->ir_current_ =
1392 CORBA::IDLType::_duplicate (extant_def.in ());
1394 CORBA::Container_ptr used_scope =
1395 CORBA::Container::_nil ();
1397 // Pop the new IR object back off the scope stack.
1398 if (be_global->ifr_scopes ().pop (used_scope) != 0)
1400 ORBSVCS_ERROR_RETURN ((
1401 LM_ERROR,
1402 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
1403 ACE_TEXT ("visit_eventtype -")
1404 ACE_TEXT (" scope pop failed\n")
1410 else
1412 // @@ (JP) I think we're ok here without a check:
1413 // not defined/not added - visit_valuetype_fwd will have
1414 // detected a clobber.
1415 // not defined/added - not possible.
1416 // defined/not added - takes the other branch.
1417 // defined/added - we're ok.
1418 this->ir_current_ =
1419 CORBA::IDLType::_narrow (prev_def.in ());
1423 catch (const CORBA::Exception& ex)
1425 ex._tao_print_exception (ACE_TEXT ("visit_eventtype"));
1427 return -1;
1430 return 0;
1434 ifr_adding_visitor::visit_eventtype_fwd (AST_EventTypeFwd *node)
1436 if (node->imported () && !be_global->do_included_files ())
1438 return 0;
1441 AST_Interface *v = node->full_definition ();
1445 // Is this interface already in the respository?
1446 CORBA::Contained_var prev_def =
1447 be_global->repository ()->lookup_id (v->repoID ());
1449 if (CORBA::is_nil (prev_def.in ()))
1451 // If our full definition is found in this IDL file, we go
1452 // ahead and create the full entry now.
1453 // The forward declared valuetype is not defined anywhere
1454 // in this IDL file, so we just create an empty entry to
1455 // be replaced by a full definition in some other IDL file.
1456 CORBA::ValueDefSeq abstract_bases (0);
1457 abstract_bases.length (0);
1458 CORBA::InterfaceDefSeq supported (0);
1459 supported.length (0);
1460 CORBA::ExtInitializerSeq initializers (0);
1461 initializers.length (0);
1463 CORBA::Container_ptr current_scope =
1464 CORBA::Container::_nil ();
1466 if (be_global->ifr_scopes ().top (current_scope) == 0)
1468 CORBA::ComponentIR::Container_var ccm_scope =
1469 CORBA::ComponentIR::Container::_narrow (
1470 current_scope
1473 CORBA::Boolean abstract =
1474 static_cast<CORBA::Boolean> (v->is_abstract ());
1476 this->ir_current_ =
1477 ccm_scope->create_event (
1478 v->repoID (),
1479 v->local_name ()->get_string (),
1480 v->version (),
1481 0, // 'custom' not handled yet
1482 abstract,
1483 CORBA::ValueDef::_nil (),
1484 0, // 'truncatable' not handled yet
1485 abstract_bases,
1486 supported,
1487 initializers
1490 else
1492 ORBSVCS_ERROR_RETURN ((
1493 LM_ERROR,
1494 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
1495 ACE_TEXT ("visit_eventtype_fwd -")
1496 ACE_TEXT (" scope stack is empty\n")
1502 node->ifr_added (true);
1503 v->ifr_fwd_added (true);
1506 catch (const CORBA::Exception& ex)
1508 ex._tao_print_exception (ACE_TEXT ("visit_eventtype_fwd"));
1510 return -1;
1513 return 0;
1517 ifr_adding_visitor::visit_home (AST_Home *node)
1519 if (node->imported () && !be_global->do_included_files ())
1521 return 0;
1526 // Is this interface already in the respository?
1527 CORBA::Contained_var prev_def =
1528 be_global->repository ()->lookup_id (node->repoID ());
1530 // If not, create a new entry.
1531 if (CORBA::is_nil (prev_def.in ()))
1533 int status = this->create_home_def (node);
1535 return status;
1537 else
1539 // There is already an entry in the repository. If the interface is
1540 // defined and has not already been populated, we do so
1541 // now. If it is not yet defined or the full definition has already
1542 // been added to the repository, we just update the current IR object
1543 // holder.
1544 if (node->is_defined () && !node->ifr_added ())
1546 // If we are here and the line below is true, then either
1547 // 1. We are defining an undefined forward declaration
1548 // from a previously processed IDL file, or
1549 // 2. We are clobbering a previous definition, either of the
1550 // node type or of some other type.
1551 // If prev_def would narrow successfully to the node type, we
1552 // have NO WAY of knowing if we are defining or clobbering. So
1553 // we destroy the contents of the previous entry (we don't want
1554 // to destroy the entry itself, since it may have already been
1555 // made a member of some other entry, and destroying it would
1556 // make the containing entry's section key invalid) and repopulate.
1557 // On the other hand, if prev_def is NOT the node type, we go
1558 // ahead an attempt to create an interface, which will get an
1559 // exception from the IFR, as the spec requires.
1560 if (!node->ifr_fwd_added ())
1562 CORBA::DefinitionKind kind =
1563 prev_def->def_kind ();
1565 if (kind == CORBA::dk_Component)
1567 CORBA::ComponentIR::HomeDef_var value =
1568 CORBA::ComponentIR::HomeDef::_narrow (
1569 prev_def.in ()
1572 CORBA::ContainedSeq_var contents =
1573 value->contents (CORBA::dk_all,
1576 CORBA::ULong length = contents->length ();
1578 for (CORBA::ULong i = 0; i < length; ++i)
1580 contents[i]->destroy ();
1583 else
1585 prev_def->destroy ();
1587 int status =
1588 this->create_home_def (node);
1590 return status;
1594 // Re-populate the repository entry.
1597 else
1599 // @@ (JP) I think we're ok here without a check:
1600 // not defined/not added - visit_interface_fwd will have
1601 // detected a clobber.
1602 // not defined/added - not possible.
1603 // defined/not added - takes the other branch.
1604 // defined/added - we're ok.
1605 this->ir_current_ =
1606 CORBA::IDLType::_narrow (prev_def.in ());
1610 catch (const CORBA::Exception& ex)
1612 ex._tao_print_exception (ACE_TEXT ("visit_home"));
1614 return -1;
1617 return 0;
1621 ifr_adding_visitor::visit_structure (AST_Structure *node)
1623 if (node->imported () && !be_global->do_included_files ())
1625 return 0;
1630 CORBA::Contained_var prev_def =
1631 be_global->repository ()->lookup_id (node->repoID ());
1633 if (CORBA::is_nil (prev_def.in ()))
1635 ifr_adding_visitor_structure visitor (node);
1636 int retval = visitor.visit_structure (node);
1638 if (retval == 0)
1640 this->ir_current_ =
1641 CORBA::IDLType::_duplicate (visitor.ir_current ());
1644 return retval;
1646 else
1648 if (node->ifr_added ())
1650 // We have visited this node before in the same IDL
1651 // compilation unit - just update ir_current_.
1652 this->ir_current_ =
1653 CORBA::StructDef::_narrow (prev_def.in ());
1655 else if (node->ifr_fwd_added ())
1657 // We are seeing the full definition of a forward
1658 // declaration - just visit the scope to populate
1659 // the IFR entry while keeping the same section key
1660 // so as not to invalidate existing references.
1661 ifr_adding_visitor_structure visitor (node);
1662 int retval = visitor.visit_structure (node);
1664 if (retval == 0)
1666 this->ir_current_ =
1667 CORBA::IDLType::_duplicate (visitor.ir_current ());
1670 return retval;
1672 else
1674 // We are clobbering a previous entry
1675 // from another IDL file. In this case we do what
1676 // other ORB vendors do - destroy the original
1677 // entry, create a new one, and let the user beware.
1678 prev_def->destroy ();
1679 return this->visit_structure (node);
1683 catch (const CORBA::Exception& ex)
1685 ex._tao_print_exception (
1686 ACE_TEXT (
1687 "ifr_adding_visitor::visit_structure"));
1689 return -1;
1692 return 0;
1696 ifr_adding_visitor::visit_structure_fwd (AST_StructureFwd *node)
1698 if (node->imported () && !be_global->do_included_files ())
1700 return 0;
1705 CORBA::Contained_var prev_def =
1706 be_global->repository ()->lookup_id (node->repoID ());
1708 if (CORBA::is_nil (prev_def.in ()))
1710 CORBA::StructMemberSeq dummyMembers;
1711 dummyMembers.length (0);
1712 CORBA::Container_ptr current_scope = CORBA::Container::_nil ();
1714 if (be_global->ifr_scopes ().top (current_scope) != 0)
1716 ORBSVCS_ERROR_RETURN ((
1717 LM_ERROR,
1718 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
1719 ACE_TEXT ("visit_structure_fwd -")
1720 ACE_TEXT (" scope stack is empty\n")
1726 CORBA::StructDef_var struct_def =
1727 current_scope->create_struct (
1728 node->repoID (),
1729 node->local_name ()->get_string (),
1730 node->version (),
1731 dummyMembers
1734 node->full_definition ()->ifr_fwd_added (true);
1737 catch (const CORBA::Exception& ex)
1739 ex._tao_print_exception (ACE_TEXT ("ifr_adding_visitor::")
1740 ACE_TEXT ("visit_structure_fwd"));
1742 return -1;
1745 return 0;
1749 ifr_adding_visitor::visit_exception (AST_Exception *node)
1751 if (node->imported () && !be_global->do_included_files ())
1753 return 0;
1756 ifr_adding_visitor_exception visitor (node,
1757 this->in_reopened_);
1759 // No point in updating ir_current_ here because
1760 // ExceptionDef is not an IDLType.
1762 return visitor.visit_exception (node);
1766 ifr_adding_visitor::visit_enum (AST_Enum *node)
1768 if (node->imported () && !be_global->do_included_files ())
1770 return 0;
1775 // Is this enum already in the respository?
1776 CORBA::Contained_var prev_def =
1777 be_global->repository ()->lookup_id (node->repoID ());
1779 // If not, create a new entry.
1780 if (CORBA::is_nil (prev_def.in ()))
1782 CORBA::ULong member_count =
1783 static_cast<CORBA::ULong> (node->member_count ());
1785 CORBA::EnumMemberSeq members (member_count);
1786 members.length (member_count);
1788 UTL_ScopedName *member_name = 0;
1790 // Get a list of the member names.
1791 for (CORBA::ULong i = 0; i < member_count; ++i)
1793 member_name = node->value_to_name (i);
1795 members[i] =
1796 CORBA::string_dup (
1797 member_name->last_component ()->get_string ()
1801 CORBA::Container_ptr current_scope =
1802 CORBA::Container::_nil ();
1804 if (be_global->ifr_scopes ().top (current_scope) == 0)
1806 this->ir_current_ =
1807 current_scope->create_enum (
1808 node->repoID (),
1809 node->local_name ()->get_string (),
1810 node->version (),
1811 members
1814 else
1816 ORBSVCS_ERROR_RETURN ((
1817 LM_ERROR,
1818 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_enum -")
1819 ACE_TEXT (" scope stack is empty\n")
1825 node->ifr_added (true);
1827 else
1829 // If the line below is true, we are clobbering a previous
1830 // entry (from another IDL file) of another type. In that
1831 // case we do what other ORB vendors do, and destroy the
1832 // original entry, create the new one, and let the user beware.
1833 if (!node->ifr_added ())
1835 prev_def->destroy ();
1837 return this->visit_enum (node);
1840 // There is already an entry in the repository, so just update
1841 // the current IR object holder.
1842 this->ir_current_ =
1843 CORBA::EnumDef::_narrow (prev_def.in ());
1846 catch (const CORBA::Exception& ex)
1848 ex._tao_print_exception (ACE_TEXT ("ifr_adding_visitor::visit_enum"));
1850 return -1;
1853 return 0;
1857 ifr_adding_visitor::visit_operation (AST_Operation *node)
1859 ifr_adding_visitor_operation visitor (node);
1861 return visitor.visit_operation (node);
1865 ifr_adding_visitor::visit_field (AST_Field *node)
1867 AST_Decl *scope = ScopeAsDecl (node->defined_in ());
1868 AST_Decl::NodeType nt = scope->node_type ();
1870 if (nt == AST_Decl::NT_valuetype || nt == AST_Decl::NT_eventtype)
1872 return this->create_value_member (node);
1875 AST_Type *ft = dynamic_cast<AST_Type*> (node->field_type ());
1877 if (ft == 0)
1879 ORBSVCS_ERROR_RETURN ((
1880 LM_ERROR,
1881 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
1882 ACE_TEXT ("visit_field - ")
1883 ACE_TEXT ("Bad field type\n")
1889 if (ft->ast_accept (this) == -1)
1891 ORBSVCS_ERROR_RETURN ((
1892 LM_ERROR,
1893 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
1894 ACE_TEXT ("visit_field - ")
1895 ACE_TEXT ("failed to accept visitor\n")
1901 return 0;
1905 ifr_adding_visitor::visit_attribute (AST_Attribute *node)
1907 ::CORBA::IDLType_var holder;
1911 AST_Type *type = node->field_type ();
1913 // Save to be replaced later.
1914 holder =
1915 ::CORBA::IDLType::_duplicate (this->ir_current_.in ());
1917 // Updates ir_current_.
1918 this->get_referenced_type (type);
1920 CORBA::AttributeMode mode =
1921 node->readonly () ? CORBA::ATTR_READONLY : CORBA::ATTR_NORMAL;
1923 CORBA::ExceptionDefSeq get_exceptions;
1924 this->fill_get_exceptions (get_exceptions,
1925 node);
1927 CORBA::ExceptionDefSeq set_exceptions;
1928 this->fill_set_exceptions (set_exceptions,
1929 node);
1931 CORBA::Container_ptr current_scope =
1932 CORBA::Container::_nil ();
1934 if (be_global->ifr_scopes ().top (current_scope) == 0)
1936 CORBA::DefinitionKind kind =
1937 current_scope->def_kind ();
1939 if (kind == CORBA::dk_Value || kind == CORBA::dk_Event)
1941 CORBA::ExtValueDef_var value =
1942 CORBA::ExtValueDef::_narrow (current_scope);
1944 CORBA::ExtAttributeDef_var new_def =
1945 value->create_ext_attribute (
1946 node->repoID (),
1947 node->local_name ()->get_string (),
1948 node->version (),
1949 this->ir_current_.in (),
1950 mode,
1951 get_exceptions,
1952 set_exceptions
1955 else
1957 // We are an interface, a local interface, an abstract
1958 // interface or a component. This narrow covers them all.
1959 CORBA::InterfaceAttrExtension_var iface =
1960 CORBA::InterfaceAttrExtension::_narrow (current_scope);
1962 CORBA::ExtAttributeDef_var new_def =
1963 iface->create_ext_attribute (
1964 node->repoID (),
1965 node->local_name ()->get_string (),
1966 node->version (),
1967 this->ir_current_.in (),
1968 mode,
1969 get_exceptions,
1970 set_exceptions
1974 else
1976 ORBSVCS_ERROR_RETURN ((
1977 LM_ERROR,
1978 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_attribute -")
1979 ACE_TEXT (" scope stack is empty\n")
1985 catch (const CORBA::Exception& ex)
1987 ex._tao_print_exception (ACE_TEXT ("visit_attribute"));
1989 return -1;
1992 // Restore entry of component or interface.
1993 this->ir_current_ =
1994 ::CORBA::IDLType::_duplicate (holder.in ());
1996 return 0;
2000 ifr_adding_visitor::visit_union (AST_Union *node)
2002 if (node->imported () && !be_global->do_included_files ())
2004 return 0;
2009 CORBA::Contained_var prev_def =
2010 be_global->repository ()->lookup_id (node->repoID ());
2012 if (CORBA::is_nil (prev_def.in ()))
2014 ifr_adding_visitor_union visitor (node);
2015 int retval = visitor.visit_union (node);
2017 if (retval == 0)
2019 this->ir_current_ =
2020 CORBA::IDLType::_duplicate (visitor.ir_current ());
2023 return retval;
2025 else
2027 if (node->ifr_added ())
2029 // We have visited this node before in the same IDL
2030 // compilation unit - just update ir_current_.
2031 this->ir_current_ =
2032 CORBA::UnionDef::_narrow (prev_def.in ());
2034 else if (node->ifr_fwd_added ())
2036 // We are seeing the full definition of a forward
2037 // declaration - just visit the scope to populate
2038 // the IFR entry while keeping the same section key
2039 // so as not to invalidate existing references.
2040 ifr_adding_visitor_union visitor (node);
2041 int retval = visitor.visit_union (node);
2043 if (retval == 0)
2045 this->ir_current_ =
2046 CORBA::IDLType::_duplicate (visitor.ir_current ());
2049 return retval;
2051 else
2053 // We are clobbering a previous entry
2054 // from another IDL file. In this case we do what
2055 // other ORB vendors do - destroy the original
2056 // entry, create a new one, and let the user beware.
2057 prev_def->destroy ();
2058 return this->visit_union (node);
2062 catch (const CORBA::Exception& ex)
2064 ex._tao_print_exception (ACE_TEXT ("ifr_adding_visitor::visit_union"));
2066 return -1;
2069 return 0;
2073 ifr_adding_visitor::visit_union_fwd (AST_UnionFwd *node)
2075 if (node->imported () && !be_global->do_included_files ())
2077 return 0;
2082 CORBA::Contained_var prev_def =
2083 be_global->repository ()->lookup_id (node->repoID ());
2085 if (CORBA::is_nil (prev_def.in ()))
2087 CORBA::UnionMemberSeq dummyMembers;
2088 dummyMembers.length (0);
2089 CORBA::Container_ptr current_scope = CORBA::Container::_nil ();
2091 if (be_global->ifr_scopes ().top (current_scope) != 0)
2093 ORBSVCS_ERROR_RETURN ((
2094 LM_ERROR,
2095 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2096 ACE_TEXT ("visit_union_fwd -")
2097 ACE_TEXT (" scope stack is empty\n")
2103 CORBA::UnionDef_var union_def =
2104 current_scope->create_union (
2105 node->repoID (),
2106 node->local_name ()->get_string (),
2107 node->version (),
2108 CORBA::IDLType::_nil (),
2109 dummyMembers
2112 node->full_definition ()->ifr_fwd_added (true);
2115 catch (const CORBA::Exception& ex)
2117 ex._tao_print_exception (ACE_TEXT ("ifr_adding_visitor::")
2118 ACE_TEXT ("visit_union_fwd"));
2120 return -1;
2123 return 0;
2127 ifr_adding_visitor::visit_constant (AST_Constant *node)
2129 if (node->imported () && !be_global->do_included_files ())
2131 return 0;
2134 const char *id = node->repoID ();
2138 CORBA::Contained_var prev_def =
2139 be_global->repository ()->lookup_id (id);
2141 // Nothing prevents this constant's repo id from already being
2142 // in the repository as another type, if it came from another
2143 // IDL file whose generated code is not linked to the generated
2144 // code from this IDL file. So we check here before we make a
2145 // call on ir_current_.
2146 if (!CORBA::is_nil (prev_def.in ()))
2148 // If the line below is true, we are clobbering a previous
2149 // entry (from another IDL file) of another type. In that
2150 // case we do what other ORB vendors do, and destroy the
2151 // original entry, create the new one, and let the user beware.
2152 if (!node->ifr_added ())
2154 prev_def->destroy ();
2156 else
2158 // The node is referenced in an array size, string bound
2159 // or sequence bound - no action needed in the IFR.
2160 return 0;
2164 AST_Expression::ExprType et = node->et ();
2165 AST_Expression *cv = node->constant_value ();
2167 /// @@@ (JP 2007-12-12) I've removed code to check
2168 /// for constants of typedefs. The CORBA document
2169 /// formal/2004-03-12 (CORBA 3.0.3) says in section
2170 /// 10.5.8.1 that the type of a constant in the IFR must be
2171 /// 'one of the primitive types allowed in constant
2172 /// declarations'. So for constants of typedefs we store
2173 /// the underlying type in the IFR.
2175 if (et == AST_Expression::EV_enum)
2177 // This constant's type is an enum - look up the enum member
2178 // representing the value, then get the enclosing enum to pass
2179 // to create_constant().
2180 AST_Decl *enum_val =
2181 node->defined_in ()->lookup_by_name (cv->n (), true);
2182 AST_Decl *d = ScopeAsDecl (enum_val->defined_in ());
2184 CORBA::Contained_var contained =
2185 be_global->repository ()->lookup_id (d->repoID ());
2187 this->ir_current_ = CORBA::IDLType::_narrow (contained.in ());
2189 else
2191 // This constant's type is a primitive type - fetch it from the
2192 // repo and pass it to create_constant().
2193 CORBA::PrimitiveKind pkind = this->expr_type_to_pkind (et);
2195 this->ir_current_ =
2196 be_global->repository ()->get_primitive (pkind);
2199 CORBA::Any any;
2200 this->load_any (cv->ev (), any);
2202 CORBA::Container_ptr current_scope = CORBA::Container::_nil ();
2204 if (be_global->ifr_scopes ().top (current_scope) == 0)
2206 CORBA::ConstantDef_var new_def =
2207 current_scope->create_constant (
2209 node->local_name ()->get_string (),
2210 node->version (),
2211 this->ir_current_.in (),
2215 else
2217 ORBSVCS_ERROR_RETURN ((
2218 LM_ERROR,
2219 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_constant -")
2220 ACE_TEXT (" scope stack is empty\n")
2226 catch (const CORBA::Exception& ex)
2228 ex._tao_print_exception (ACE_TEXT ("visit_constant"));
2230 return -1;
2233 return 0;
2237 ifr_adding_visitor::visit_array (AST_Array *node)
2241 bool owned = false;
2242 AST_Type *bt = node->base_type ();
2243 UTL_Scope *bts = bt->defined_in ();
2244 UTL_Scope *ns = node->defined_in ();
2246 if (bts == ns && !bt->ifr_added ())
2248 // What we most likely have if we get here is an
2249 // anonymous array member whose base type is
2250 // defined as part of the array declaration.
2251 // Setting the boolean to TRUE and passing it
2252 // to element_type() will force the base type
2253 // to be added to the IFR before anything else
2254 // happens.
2255 owned = true;
2258 this->element_type (bt, owned);
2260 AST_Expression **dims = node->dims ();
2262 for (unsigned long i = node->n_dims (); i > 0; --i)
2264 this->ir_current_ =
2265 be_global->repository ()->create_array (
2266 dims[i - 1]->ev ()->u.ulval,
2267 this->ir_current_.in ()
2271 catch (const CORBA::Exception& ex)
2273 ex._tao_print_exception (ACE_TEXT ("visit_array"));
2275 return -1;
2278 return 0;
2282 ifr_adding_visitor::visit_sequence (AST_Sequence *node)
2286 this->element_type (node->base_type ());
2288 this->ir_current_ =
2289 be_global->repository ()->create_sequence (
2290 node->max_size ()->ev ()->u.ulval,
2291 this->ir_current_.in ()
2294 catch (const CORBA::Exception& ex)
2296 ex._tao_print_exception (ACE_TEXT ("visit_sequence"));
2298 return -1;
2301 return 0;
2305 ifr_adding_visitor::visit_map (AST_Map *)
2307 ORBSVCS_ERROR_RETURN ((
2308 LM_ERROR,
2309 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_map -")
2310 ACE_TEXT (" maps are not supported\n")
2317 ifr_adding_visitor::visit_string (AST_String *node)
2319 AST_Expression *ex = node->max_size ();
2321 AST_Expression::AST_ExprValue *ev = ex->ev ();
2323 CORBA::ULong bound = static_cast<CORBA::ULong> (ev->u.ulval);
2327 if (node->node_type () == AST_Decl::NT_string)
2329 this->ir_current_ =
2330 be_global->repository ()->create_string (bound);
2332 else
2334 this->ir_current_ =
2335 be_global->repository ()->create_wstring (bound);
2339 catch (const CORBA::Exception& ex)
2341 ex._tao_print_exception (ACE_TEXT ("visit_string"));
2343 return -1;
2346 return 0;
2350 ifr_adding_visitor::visit_typedef (AST_Typedef *node)
2352 if (node->imported () && !be_global->do_included_files ())
2354 return 0;
2359 this->element_type (node->base_type (), node->owns_base_type ());
2361 CORBA::Container_ptr current_scope =
2362 CORBA::Container::_nil ();
2364 if (be_global->ifr_scopes ().top (current_scope) == 0)
2366 this->ir_current_ =
2367 current_scope->create_alias (
2368 node->repoID (),
2369 node->local_name ()->get_string (),
2370 node->version (),
2371 this->ir_current_.in ()
2374 else
2376 ORBSVCS_ERROR_RETURN ((
2377 LM_ERROR,
2378 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_typedef -")
2379 ACE_TEXT (" scope stack is empty\n")
2385 node->ifr_added (true);
2387 catch (const CORBA::Exception& ex)
2389 if (!this->allow_duplicate_typedefs_)
2391 ex._tao_print_exception (ACE_TEXT ("visit_typedef"));
2393 return -1;
2395 else
2397 ORBSVCS_DEBUG ((LM_DEBUG,
2398 "%s %s\n",
2399 ACE_TEXT ("ifr_adding_visitor::visit_typedef - ignoring duplicate typedef"),
2400 node->local_name ()->get_string ()));
2404 return 0;
2408 ifr_adding_visitor::visit_root (AST_Root *node)
2410 if (be_global->ifr_scopes ().push (be_global->repository ()) != 0)
2412 ORBSVCS_ERROR_RETURN ((
2413 LM_ERROR,
2414 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_root -")
2415 ACE_TEXT (" scope push failed\n")
2421 if (this->visit_scope (node) == -1)
2423 ORBSVCS_ERROR_RETURN ((
2424 LM_ERROR,
2425 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_root -")
2426 ACE_TEXT (" visit_scope failed\n")
2432 CORBA::Container_ptr tmp =
2433 CORBA::Container::_nil ();
2435 if (be_global->ifr_scopes ().pop (tmp) != 0)
2437 ORBSVCS_ERROR_RETURN ((
2438 LM_ERROR,
2439 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_root -")
2440 ACE_TEXT (" scope pop failed\n")
2446 return 0;
2450 ifr_adding_visitor::visit_native (AST_Native *node)
2452 if (node->imported () && !be_global->do_included_files ())
2454 return 0;
2459 CORBA::Contained_var prev_def =
2460 be_global->repository ()->lookup_id (node->repoID ());
2462 if (CORBA::is_nil (prev_def.in ()))
2464 CORBA::Container_ptr current_scope =
2465 CORBA::Container::_nil ();
2467 if (be_global->ifr_scopes ().top (current_scope) == 0)
2469 this->ir_current_ =
2470 current_scope->create_native (
2471 node->repoID (),
2472 node->local_name ()->get_string (),
2473 node->version ()
2476 else
2478 ORBSVCS_ERROR_RETURN ((
2479 LM_ERROR,
2480 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_native -")
2481 ACE_TEXT (" scope stack is empty\n")
2487 node->ifr_added (true);
2489 else
2491 // If the line below is true, we are clobbering a previous
2492 // entry (from another IDL file) of another type. In that
2493 // case we do what other ORB vendors do, and destroy the
2494 // original entry, create the new one, and let the user beware.
2495 if (!node->ifr_added ())
2497 prev_def->destroy ();
2499 // This call will take the other branch.
2500 return this->visit_native (node);
2503 this->ir_current_ =
2504 CORBA::NativeDef::_narrow (prev_def.in ());
2507 catch (const CORBA::Exception& ex)
2509 ex._tao_print_exception (ACE_TEXT ("visit_native"));
2511 return -1;
2514 return 0;
2517 CORBA::PrimitiveKind
2518 ifr_adding_visitor::expr_type_to_pkind (AST_Expression::ExprType et)
2520 switch (et)
2522 case AST_Expression::EV_short:
2523 return CORBA::pk_short;
2524 case AST_Expression::EV_ushort:
2525 return CORBA::pk_ushort;
2526 case AST_Expression::EV_long:
2527 return CORBA::pk_long;
2528 case AST_Expression::EV_ulong:
2529 return CORBA::pk_ulong;
2530 case AST_Expression::EV_longlong:
2531 return CORBA::pk_longlong;
2532 case AST_Expression::EV_ulonglong:
2533 return CORBA::pk_ulonglong;
2534 case AST_Expression::EV_float:
2535 return CORBA::pk_float;
2536 case AST_Expression::EV_double:
2537 return CORBA::pk_double;
2538 case AST_Expression::EV_longdouble:
2539 return CORBA::pk_longdouble;
2540 case AST_Expression::EV_char:
2541 return CORBA::pk_char;
2542 case AST_Expression::EV_wchar:
2543 return CORBA::pk_wchar;
2544 case AST_Expression::EV_octet:
2545 return CORBA::pk_octet;
2546 case AST_Expression::EV_bool:
2547 return CORBA::pk_boolean;
2548 case AST_Expression::EV_string:
2549 return CORBA::pk_string;
2550 case AST_Expression::EV_wstring:
2551 return CORBA::pk_wstring;
2552 case AST_Expression::EV_any:
2553 return CORBA::pk_any;
2554 case AST_Expression::EV_void:
2555 return CORBA::pk_void;
2556 case AST_Expression::EV_none:
2557 return CORBA::pk_null;
2558 default:
2559 return CORBA::pk_null;
2563 CORBA::PrimitiveKind
2564 ifr_adding_visitor::predefined_type_to_pkind (AST_PredefinedType *node)
2566 switch (node->pt ())
2568 case AST_PredefinedType::PT_short:
2569 return CORBA::pk_short;
2570 case AST_PredefinedType::PT_ushort:
2571 return CORBA::pk_ushort;
2572 case AST_PredefinedType::PT_long:
2573 return CORBA::pk_long;
2574 case AST_PredefinedType::PT_ulong:
2575 return CORBA::pk_ulong;
2576 case AST_PredefinedType::PT_longlong:
2577 return CORBA::pk_longlong;
2578 case AST_PredefinedType::PT_ulonglong:
2579 return CORBA::pk_ulonglong;
2580 case AST_PredefinedType::PT_float:
2581 return CORBA::pk_float;
2582 case AST_PredefinedType::PT_double:
2583 return CORBA::pk_double;
2584 case AST_PredefinedType::PT_longdouble:
2585 return CORBA::pk_longdouble;
2586 case AST_PredefinedType::PT_char:
2587 return CORBA::pk_char;
2588 case AST_PredefinedType::PT_wchar:
2589 return CORBA::pk_wchar;
2590 case AST_PredefinedType::PT_octet:
2591 return CORBA::pk_octet;
2592 case AST_PredefinedType::PT_boolean:
2593 return CORBA::pk_boolean;
2594 case AST_PredefinedType::PT_any:
2595 return CORBA::pk_any;
2596 case AST_PredefinedType::PT_void:
2597 return CORBA::pk_void;
2598 case AST_PredefinedType::PT_object:
2599 return CORBA::pk_objref;
2600 case AST_PredefinedType::PT_value:
2601 return CORBA::pk_value_base;
2602 case AST_PredefinedType::PT_pseudo:
2604 const char *local_name = node->local_name ()->get_string ();
2606 if (!ACE_OS::strcmp (local_name, "Principal"))
2608 return CORBA::pk_Principal;
2610 else
2612 return CORBA::pk_TypeCode;
2615 default:
2616 return CORBA::pk_null;
2620 void
2621 ifr_adding_visitor::load_any (AST_Expression::AST_ExprValue *ev,
2622 CORBA::Any &any)
2624 switch (ev->et)
2626 case AST_Expression::EV_short:
2627 any <<= ev->u.sval;
2628 break;
2629 case AST_Expression::EV_ushort:
2630 any <<= ev->u.usval;
2631 break;
2632 case AST_Expression::EV_long:
2633 any <<= static_cast<CORBA::Long> (ev->u.lval);
2634 break;
2635 case AST_Expression::EV_ulong:
2636 any <<= static_cast<CORBA::ULong> (ev->u.ulval);
2637 break;
2638 case AST_Expression::EV_longlong:
2639 any <<= ev->u.llval;
2640 break;
2641 case AST_Expression::EV_ulonglong:
2642 any <<= ev->u.ullval;
2643 break;
2644 case AST_Expression::EV_float:
2645 any <<= ev->u.fval;
2646 break;
2647 case AST_Expression::EV_double:
2648 any <<= ev->u.dval;
2649 break;
2650 #if 0
2651 case AST_Expression::EV_longdouble:
2652 // Not implemented in IDL compiler.
2653 #endif
2654 case AST_Expression::EV_char:
2655 any <<= CORBA::Any::from_char (ev->u.cval);
2656 break;
2657 case AST_Expression::EV_wchar:
2658 any <<= CORBA::Any::from_wchar (ev->u.wcval);
2659 break;
2660 case AST_Expression::EV_octet:
2661 any <<= CORBA::Any::from_octet (ev->u.oval);
2662 break;
2663 case AST_Expression::EV_bool:
2664 any <<= CORBA::Any::from_boolean ((CORBA::Boolean) ev->u.bval);
2665 break;
2666 case AST_Expression::EV_string:
2667 any <<= ev->u.strval->get_string ();
2668 break;
2669 case AST_Expression::EV_wstring:
2671 char *str = ev->u.wstrval;
2672 size_t len = ACE_OS::strlen (str);
2673 CORBA::WChar *wstr = 0;
2674 ACE_NEW (wstr,
2675 CORBA::WChar[len + 1]);
2677 for (size_t i = 0; i < len; ++i)
2679 wstr[i] = static_cast<CORBA::WChar> (str[i]);
2682 wstr[len] = 0;
2683 any <<= wstr;
2684 delete [] wstr;
2685 break;
2687 case AST_Expression::EV_enum:
2688 any <<= static_cast<CORBA::ULong> (ev->u.eval);
2689 break;
2690 default:
2691 break;
2695 void
2696 ifr_adding_visitor::element_type (AST_Type *base_type, bool owned)
2698 AST_Decl::NodeType nt = base_type->node_type ();
2699 bool no_repo_id = nt == AST_Decl::NT_array
2700 || nt == AST_Decl::NT_sequence
2701 || base_type->anonymous ();
2703 if (no_repo_id || owned)
2705 if (base_type->ast_accept (this) == -1)
2707 ORBSVCS_ERROR ((
2708 LM_ERROR,
2709 ACE_TEXT ("(%N:%l) ifr_adding_visitor::element_type -")
2710 ACE_TEXT (" failed to accept visitor\n")
2713 throw Bailout ();
2716 else
2718 CORBA::Contained_var contained =
2719 be_global->repository ()->lookup_id (base_type->repoID ());
2721 if (CORBA::is_nil (contained.in ()))
2723 ORBSVCS_ERROR ((
2724 LM_ERROR,
2725 ACE_TEXT ("(%N:%l) ifr_adding_visitor::element_type -")
2726 ACE_TEXT (" lookup_id failed\n")
2729 throw Bailout ();
2732 this->ir_current_ = CORBA::IDLType::_narrow (contained.in ());
2737 ifr_adding_visitor::create_interface_def (AST_Interface *node)
2739 CORBA::ULong n_parents = static_cast<CORBA::ULong> (node->n_inherits ());
2740 AST_Type **parents = node->inherits ();
2741 CORBA::Contained_var result;
2742 CORBA::AbstractInterfaceDefSeq abs_bases;
2743 CORBA::InterfaceDefSeq bases;
2745 if (node->is_abstract ())
2747 abs_bases.length (n_parents);
2749 // Construct a list of the parents.
2750 for (CORBA::ULong i = 0; i < n_parents; ++i)
2752 AST_Interface *intf =
2753 dynamic_cast<AST_Interface*> (parents[i]);
2755 if (intf == 0)
2757 ORBSVCS_ERROR_RETURN ((
2758 LM_ERROR,
2759 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2760 ACE_TEXT ("create_interface_def -")
2761 ACE_TEXT (" parent %s is not an interface\n"),
2762 parents[i]->full_name ()),
2763 -1);
2766 result =
2767 be_global->repository ()->lookup_id (intf->repoID ());
2769 // If we got to visit_interface() from a forward declared interface,
2770 // this node may not yet be in the repository.
2771 if (CORBA::is_nil (result.in ()))
2773 int status = this->create_interface_def (intf);
2775 if (status != 0)
2777 ORBSVCS_ERROR_RETURN ((
2778 LM_ERROR,
2779 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2780 ACE_TEXT ("create_interface_def -")
2781 ACE_TEXT (" parent interfacedef creation failed\n")),
2782 -1);
2785 bases[i] =
2786 CORBA::AbstractInterfaceDef::_narrow (this->ir_current_.in ());
2788 else
2790 abs_bases[i] =
2791 CORBA::AbstractInterfaceDef::_narrow (result.in ());
2794 if (CORBA::is_nil (abs_bases[i]))
2796 ORBSVCS_ERROR_RETURN ((
2797 LM_ERROR,
2798 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2799 ACE_TEXT ("create_interface_def -")
2800 ACE_TEXT (" CORBA::InterfaceDef::_narrow failed\n")
2807 else
2809 bases.length (n_parents);
2811 // Construct a list of the parents.
2812 for (CORBA::ULong i = 0; i < n_parents; ++i)
2814 AST_Interface *intf =
2815 dynamic_cast<AST_Interface*> (parents[i]);
2817 if (intf == 0)
2819 ORBSVCS_ERROR_RETURN ((
2820 LM_ERROR,
2821 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2822 ACE_TEXT ("create_interface_def -")
2823 ACE_TEXT (" parent %s is not an interface\n"),
2824 parents[i]->full_name ()),
2825 -1);
2828 result =
2829 be_global->repository ()->lookup_id (intf->repoID ());
2831 // If we got to visit_interface() from a forward declared interface,
2832 // this node may not yet be in the repository.
2833 if (CORBA::is_nil (result.in ()))
2835 int status = this->create_interface_def (intf);
2837 if (status != 0)
2839 ORBSVCS_ERROR_RETURN ((
2840 LM_ERROR,
2841 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2842 ACE_TEXT ("create_interface_def -")
2843 ACE_TEXT (" parent interfacedef creation failed\n")
2849 bases[i] = CORBA::InterfaceDef::_narrow (this->ir_current_.in ());
2851 else
2853 bases[i] = CORBA::InterfaceDef::_narrow (result.in ());
2856 if (CORBA::is_nil (bases[i]))
2858 ORBSVCS_ERROR_RETURN ((
2859 LM_ERROR,
2860 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2861 ACE_TEXT ("create_interface_def -")
2862 ACE_TEXT (" CORBA::InterfaceDef::_narrow failed\n")
2870 CORBA::Container_ptr current_scope =
2871 CORBA::Container::_nil ();
2873 if (be_global->ifr_scopes ().top (current_scope) == 0)
2875 CORBA::InterfaceDef_var new_def;
2877 if (node->is_local ())
2879 new_def =
2880 current_scope->create_local_interface (
2881 node->repoID (),
2882 node->local_name ()->get_string (),
2883 node->version (),
2884 bases
2887 else if (node->is_abstract ())
2889 new_def =
2890 current_scope->create_abstract_interface (
2891 node->repoID (),
2892 node->local_name ()->get_string (),
2893 node->version (),
2894 abs_bases
2897 else
2899 new_def =
2900 current_scope->create_interface (
2901 node->repoID (),
2902 node->local_name ()->get_string (),
2903 node->version (),
2904 bases
2909 node->ifr_added (true);
2911 // Push the new IR object onto the scope stack.
2912 CORBA::Container_var new_scope =
2913 CORBA::Container::_narrow (new_def.in ());
2915 if (be_global->ifr_scopes ().push (new_scope.in ()) != 0)
2917 ORBSVCS_ERROR_RETURN ((
2918 LM_ERROR,
2919 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2920 ACE_TEXT ("create_interface_def -")
2921 ACE_TEXT (" scope push failed\n")
2927 // Visit the members, if any.
2928 if (this->visit_scope (node) == -1)
2930 ORBSVCS_ERROR_RETURN ((
2931 LM_ERROR,
2932 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2933 ACE_TEXT ("create_interface_def -")
2934 ACE_TEXT (" visit_scope failed\n")
2940 // This spot in the AST doesn't necessarily have to be the
2941 // interface definition - it could be any reference to it.
2942 // The front end will already have fully defined it, so all
2943 // the info is available anywhere. So it's a good idea to
2944 // update the current IR object holder now. This will
2945 // consume the objref pointer.
2946 this->ir_current_ =
2947 CORBA::IDLType::_duplicate (new_def.in ());
2949 CORBA::Container_ptr used_scope =
2950 CORBA::Container::_nil ();
2952 // Pop the new IR object back off the scope stack.
2953 if (be_global->ifr_scopes ().pop (used_scope) != 0)
2955 ORBSVCS_ERROR_RETURN ((
2956 LM_ERROR,
2957 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2958 ACE_TEXT ("create_interface_def -")
2959 ACE_TEXT (" scope pop failed\n")
2965 else
2967 ORBSVCS_ERROR_RETURN ((
2968 LM_ERROR,
2969 ACE_TEXT ("(%N:%l) ifr_adding_visitor::create_interface_def -")
2970 ACE_TEXT (" scope stack is empty\n")
2976 return 0;
2980 ifr_adding_visitor::create_value_def (AST_ValueType *node)
2982 CORBA::Container_ptr current_scope =
2983 CORBA::Container::_nil ();
2985 if (be_global->ifr_scopes ().top (current_scope) == 0)
2987 CORBA::ValueDef_var base_value;
2988 this->fill_base_value (base_value.out (),
2989 node);
2991 CORBA::ValueDefSeq abstract_base_values;
2992 this->fill_abstract_base_values (abstract_base_values,
2993 node);
2995 CORBA::InterfaceDefSeq supported_interfaces;
2996 this->fill_supported_interfaces (supported_interfaces,
2997 node);
2999 CORBA::ExtInitializerSeq initializers;
3000 this->fill_initializers (initializers,
3001 node);
3003 CORBA::ExtValueDef_var new_def =
3004 current_scope->create_ext_value (
3005 node->repoID (),
3006 node->local_name ()->get_string (),
3007 node->version (),
3008 static_cast<CORBA::Boolean> (node->custom ()),
3009 static_cast<CORBA::Boolean> (node->is_abstract ()),
3010 base_value.in (),
3011 static_cast<CORBA::Boolean> (node->truncatable ()),
3012 abstract_base_values,
3013 supported_interfaces,
3014 initializers
3017 node->ifr_added (true);
3019 // Push the new IR object onto the scope stack.
3020 CORBA::Container_var new_scope =
3021 CORBA::Container::_narrow (new_def.in ());
3023 if (be_global->ifr_scopes ().push (new_scope.in ()) != 0)
3025 ORBSVCS_ERROR_RETURN ((
3026 LM_ERROR,
3027 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3028 ACE_TEXT ("create_value_def -")
3029 ACE_TEXT (" scope push failed\n")
3035 // Visit the members, if any.
3036 if (this->visit_scope (node) == -1)
3038 ORBSVCS_ERROR_RETURN ((
3039 LM_ERROR,
3040 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3041 ACE_TEXT ("create_value_def -")
3042 ACE_TEXT (" visit_scope failed\n")
3048 // This spot in the AST doesn't necessarily have to be the
3049 // interface definition - it could be any reference to it.
3050 // The front end will already have fully defined it, so all
3051 // the info is available anywhere. So it's a good idea to
3052 // update the current IR object holder now. This will
3053 // consume the objref pointer.
3054 this->ir_current_ =
3055 CORBA::IDLType::_duplicate (new_def.in ());
3057 CORBA::Container_ptr used_scope =
3058 CORBA::Container::_nil ();
3060 // Pop the new IR object back off the scope stack.
3061 if (be_global->ifr_scopes ().pop (used_scope) != 0)
3063 ORBSVCS_ERROR_RETURN ((
3064 LM_ERROR,
3065 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3066 ACE_TEXT ("create_value_def -")
3067 ACE_TEXT (" scope pop failed\n")
3073 else
3075 ORBSVCS_ERROR_RETURN ((
3076 LM_ERROR,
3077 ACE_TEXT ("(%N:%l) ifr_adding_visitor::create_value_def -")
3078 ACE_TEXT (" scope stack is empty\n")
3084 return 0;
3088 ifr_adding_visitor::create_component_def (AST_Component *node)
3090 CORBA::Container_ptr current_scope =
3091 CORBA::Container::_nil ();
3093 if (be_global->ifr_scopes ().top (current_scope) == 0)
3095 CORBA::ComponentIR::ComponentDef_var base_component;
3096 this->fill_base_component (base_component.out (),
3097 node);
3099 CORBA::InterfaceDefSeq supported_interfaces;
3100 this->fill_supported_interfaces (supported_interfaces,
3101 node);
3103 CORBA::ComponentIR::Container_var ccm_scope =
3104 CORBA::ComponentIR::Container::_narrow (current_scope);
3106 CORBA::ComponentIR::ComponentDef_var new_def =
3107 ccm_scope->create_component (node->repoID (),
3108 node->local_name ()->get_string (),
3109 node->version (),
3110 base_component.in (),
3111 supported_interfaces);
3113 node->ifr_added (true);
3115 if (be_global->ifr_scopes ().push (new_def.in ()) != 0)
3117 ORBSVCS_ERROR_RETURN ((
3118 LM_ERROR,
3119 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3120 ACE_TEXT ("create_component_def -")
3121 ACE_TEXT (" scope push failed\n")
3127 // This spot in the AST doesn't necessarily have to be the
3128 // interface definition - it could be any reference to it.
3129 // The front end will already have fully defined it, so all
3130 // the info is available anywhere. So it's a good idea to
3131 // update the current IR object holder now. This will
3132 // consume the objref pointer.
3133 this->ir_current_ =
3134 CORBA::IDLType::_duplicate (new_def.in ());
3136 // Visit the members, if any.
3137 if (this->visit_scope (node) == -1)
3139 ORBSVCS_ERROR_RETURN ((
3140 LM_ERROR,
3141 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3142 ACE_TEXT ("create_component_def -")
3143 ACE_TEXT (" visit_scope failed\n")
3149 CORBA::Container_ptr used_scope =
3150 CORBA::Container::_nil ();
3152 // Pop the new IR object back off the scope stack.
3153 if (be_global->ifr_scopes ().pop (used_scope) != 0)
3155 ORBSVCS_ERROR_RETURN ((
3156 LM_ERROR,
3157 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3158 ACE_TEXT ("create_component_def -")
3159 ACE_TEXT (" scope pop failed\n")
3165 else
3167 ORBSVCS_ERROR_RETURN ((
3168 LM_ERROR,
3169 ACE_TEXT ("(%N:%l) ifr_adding_visitor::create_component_def -")
3170 ACE_TEXT (" scope stack is empty\n")
3176 return 0;
3180 ifr_adding_visitor::create_home_def (AST_Home *node)
3182 CORBA::Container_ptr current_scope =
3183 CORBA::Container::_nil ();
3185 if (be_global->ifr_scopes ().top (current_scope) == 0)
3187 CORBA::ComponentIR::HomeDef_var base_home;
3188 this->fill_base_home (base_home.out (),
3189 node);
3191 CORBA::ComponentIR::ComponentDef_var managed_component;
3192 this->fill_managed_component (managed_component.out (),
3193 node);
3195 CORBA::InterfaceDefSeq supported_interfaces;
3196 this->fill_supported_interfaces (supported_interfaces,
3197 node);
3199 CORBA::ValueDef_var primary_key;
3200 this->fill_primary_key (primary_key.out (),
3201 node);
3203 CORBA::ComponentIR::Container_var ccm_scope =
3204 CORBA::ComponentIR::Container::_narrow (current_scope);
3206 CORBA::ComponentIR::HomeDef_var new_def =
3207 ccm_scope->create_home (node->repoID (),
3208 node->local_name ()->get_string (),
3209 node->version (),
3210 base_home.in (),
3211 managed_component.in (),
3212 supported_interfaces,
3213 primary_key.in ());
3215 node->ifr_added (true);
3217 // Push the new IR object onto the scope stack.
3218 CORBA::Container_var new_scope =
3219 CORBA::Container::_narrow (new_def.in ());
3221 if (be_global->ifr_scopes ().push (new_scope.in ()) != 0)
3223 ORBSVCS_ERROR_RETURN ((
3224 LM_ERROR,
3225 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3226 ACE_TEXT ("create_home_def -")
3227 ACE_TEXT (" scope push failed\n")
3233 // Visit the members, if any.
3234 if (this->visit_scope (node) == -1)
3236 ORBSVCS_ERROR_RETURN ((
3237 LM_ERROR,
3238 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3239 ACE_TEXT ("create_home_def -")
3240 ACE_TEXT (" visit_scope failed\n")
3246 // Get the contents of these lists into the repository.
3248 this->visit_all_factories (node,
3249 new_def.in ());
3251 this->visit_all_finders (node,
3252 new_def.in ());
3254 // This spot in the AST doesn't necessarily have to be the
3255 // interface definition - it could be any reference to it.
3256 // The front end will already have fully defined it, so all
3257 // the info is available anywhere. So it's a good idea to
3258 // update the current IR object holder now. This will
3259 // consume the objref pointer.
3260 this->ir_current_ =
3261 CORBA::IDLType::_duplicate (new_def.in ());
3263 CORBA::Container_ptr used_scope =
3264 CORBA::Container::_nil ();
3266 // Pop the new IR object back off the scope stack.
3267 if (be_global->ifr_scopes ().pop (used_scope) != 0)
3269 ORBSVCS_ERROR_RETURN ((
3270 LM_ERROR,
3271 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3272 ACE_TEXT ("create_home_def -")
3273 ACE_TEXT (" scope pop failed\n")
3279 else
3281 ORBSVCS_ERROR_RETURN ((
3282 LM_ERROR,
3283 ACE_TEXT ("(%N:%l) ifr_adding_visitor::create_home_def -")
3284 ACE_TEXT (" scope stack is empty\n")
3290 return 0;
3294 ifr_adding_visitor::create_event_def (AST_EventType *node)
3296 CORBA::Container_ptr current_scope =
3297 CORBA::Container::_nil ();
3299 if (be_global->ifr_scopes ().top (current_scope) == 0)
3301 CORBA::ValueDef_var base_value;
3302 this->fill_base_value (base_value.out (),
3303 node);
3305 CORBA::ValueDefSeq abstract_base_values;
3306 this->fill_abstract_base_values (abstract_base_values,
3307 node);
3309 CORBA::InterfaceDefSeq supported_interfaces;
3310 this->fill_supported_interfaces (supported_interfaces,
3311 node);
3313 CORBA::ExtInitializerSeq initializers;
3314 this->fill_initializers (initializers,
3315 node);
3317 CORBA::ComponentIR::Container_var ccm_scope =
3318 CORBA::ComponentIR::Container::_narrow (current_scope);
3320 CORBA::ExtValueDef_var new_def =
3321 ccm_scope->create_event (
3322 node->repoID (),
3323 node->local_name ()->get_string (),
3324 node->version (),
3325 static_cast<CORBA::Boolean> (node->custom ()),
3326 static_cast<CORBA::Boolean> (node->is_abstract ()),
3327 base_value.in (),
3328 static_cast<CORBA::Boolean> (node->truncatable ()),
3329 abstract_base_values,
3330 supported_interfaces,
3331 initializers
3334 node->ifr_added (true);
3336 // Push the new IR object onto the scope stack.
3337 CORBA::Container_var new_scope =
3338 CORBA::Container::_narrow (new_def.in ());
3340 if (be_global->ifr_scopes ().push (new_scope.in ()) != 0)
3342 ORBSVCS_ERROR_RETURN ((
3343 LM_ERROR,
3344 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3345 ACE_TEXT ("create_event_def -")
3346 ACE_TEXT (" scope push failed\n")
3352 // Visit the members, if any.
3353 if (this->visit_scope (node) == -1)
3355 ORBSVCS_ERROR_RETURN ((
3356 LM_ERROR,
3357 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3358 ACE_TEXT ("create_event_def -")
3359 ACE_TEXT (" visit_scope failed\n")
3365 // This spot in the AST doesn't necessarily have to be the
3366 // interface definition - it could be any reference to it.
3367 // The front end will already have fully defined it, so all
3368 // the info is available anywhere. So it's a good idea to
3369 // update the current IR object holder now. This will
3370 // consume the objref pointer.
3371 this->ir_current_ =
3372 CORBA::IDLType::_duplicate (new_def.in ());
3374 CORBA::Container_ptr used_scope =
3375 CORBA::Container::_nil ();
3377 // Pop the new IR object back off the scope stack.
3378 if (be_global->ifr_scopes ().pop (used_scope) != 0)
3380 ORBSVCS_ERROR_RETURN ((
3381 LM_ERROR,
3382 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3383 ACE_TEXT ("create_event_def -")
3384 ACE_TEXT (" scope pop failed\n")
3390 else
3392 ORBSVCS_ERROR_RETURN ((
3393 LM_ERROR,
3394 ACE_TEXT ("(%N:%l) ifr_adding_visitor::create_event_def -")
3395 ACE_TEXT (" scope stack is empty\n")
3401 return 0;
3405 ifr_adding_visitor::create_value_member (AST_Field *node)
3409 AST_Type *bt = node->field_type ();
3410 AST_Decl::NodeType nt = bt->node_type ();
3412 // We can't use lookup_id() on these, because
3413 // they don't inherit from Contained.
3414 if (nt == AST_Decl::NT_pre_defined
3415 || nt == AST_Decl::NT_string
3416 || nt == AST_Decl::NT_wstring
3417 || nt == AST_Decl::NT_array
3418 || nt == AST_Decl::NT_sequence)
3420 /// This will put the repo entry into ir_current_.
3421 if (bt->ast_accept (this) != 0)
3423 ORBSVCS_ERROR_RETURN ((
3424 LM_ERROR,
3425 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3426 ACE_TEXT ("create_value_member -")
3427 ACE_TEXT (" visit base type failed\n")
3433 else
3435 // If the IDL is legal, this will succeed.
3436 CORBA::Contained_var holder =
3437 be_global->repository ()->lookup_id (bt->repoID ());
3439 this->ir_current_ =
3440 CORBA::IDLType::_narrow (holder.in ());
3443 CORBA::Visibility vis = CORBA::PUBLIC_MEMBER;
3445 switch (node->visibility ())
3447 case AST_Field::vis_PUBLIC:
3448 break;
3449 case AST_Field::vis_PRIVATE:
3450 vis = CORBA::PRIVATE_MEMBER;
3451 break;
3452 default:
3453 ORBSVCS_ERROR_RETURN ((
3454 LM_ERROR,
3455 ACE_TEXT ("(%N:%l) ifr_adding_visitor::create_value_member -")
3456 ACE_TEXT (" bad visibility value in node\n")
3462 CORBA::Container_ptr current_scope = CORBA::Container::_nil ();
3464 if (be_global->ifr_scopes ().top (current_scope) != 0)
3466 ORBSVCS_ERROR_RETURN ((
3467 LM_ERROR,
3468 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3469 ACE_TEXT ("create_value_member -")
3470 ACE_TEXT (" scope stack empty\n")
3476 CORBA::ValueDef_var vt =
3477 CORBA::ValueDef::_narrow (current_scope);
3479 CORBA::ValueMemberDef_var vm =
3480 vt->create_value_member (node->repoID (),
3481 node->local_name ()->get_string (),
3482 node->version (),
3483 this->ir_current_.in (),
3484 vis);
3486 catch (const CORBA::Exception& ex)
3488 ex._tao_print_exception (ACE_TEXT ("create_value_member"));
3490 return -1;
3493 return 0;
3496 void
3497 ifr_adding_visitor::get_referenced_type (AST_Type *node)
3499 switch (node->node_type ())
3501 // For anonymous types, a new IR object is be created each
3502 // time, so we just visit the node, which get the object and
3503 // updates ir_current_.
3504 case AST_Decl::NT_pre_defined:
3505 case AST_Decl::NT_string:
3506 case AST_Decl::NT_wstring:
3507 case AST_Decl::NT_array:
3508 case AST_Decl::NT_sequence:
3509 if (node->ast_accept (this) == -1)
3511 ORBSVCS_ERROR ((
3512 LM_ERROR,
3513 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3514 ACE_TEXT ("get_scope_member -")
3515 ACE_TEXT (" failed to accept visitor\n")
3519 break;
3520 // For names types, we can just look up the entry and update
3521 // ir_current_.
3522 default:
3524 CORBA::Contained_var prev_def =
3525 be_global->repository ()->lookup_id (node->repoID ());
3527 this->ir_current_ =
3528 CORBA::IDLType::_narrow (prev_def.in ());
3529 break;
3534 void
3535 ifr_adding_visitor::fill_base_value (CORBA::ValueDef_ptr &result,
3536 AST_ValueType *node)
3538 result = CORBA::ValueDef::_nil ();
3539 AST_Type *base_value = node->inherits_concrete ();
3541 if (base_value == 0)
3543 return;
3546 CORBA::Contained_var holder =
3547 be_global->repository ()->lookup_id (
3548 base_value->repoID ()
3551 if (!CORBA::is_nil (holder.in ()))
3553 result =
3554 CORBA::ValueDef::_narrow (holder.in ());
3558 void
3559 ifr_adding_visitor::fill_base_component (
3560 CORBA::ComponentIR::ComponentDef_ptr &result,
3561 AST_Component *node
3564 result = CORBA::ComponentIR::ComponentDef::_nil ();
3565 AST_Component *base_component = node->base_component ();
3567 if (base_component == 0)
3569 return;
3572 CORBA::Contained_var holder =
3573 be_global->repository ()->lookup_id (
3574 base_component->repoID ()
3577 if (!CORBA::is_nil (holder.in ()))
3579 result =
3580 CORBA::ComponentIR::ComponentDef::_narrow (holder.in ());
3584 void
3585 ifr_adding_visitor::fill_base_home (CORBA::ComponentIR::HomeDef_ptr &result,
3586 AST_Home *node)
3588 result = CORBA::ComponentIR::HomeDef::_nil ();
3589 AST_Home *base_home = node->base_home ();
3591 if (base_home == 0)
3593 return;
3596 CORBA::Contained_var holder =
3597 be_global->repository ()->lookup_id (
3598 base_home->repoID ()
3601 if (!CORBA::is_nil (holder.in ()))
3603 result =
3604 CORBA::ComponentIR::HomeDef::_narrow (holder.in ());
3606 else
3608 /// Maybe the base home is in an included IDL file - put it in
3609 /// the repository and go again.
3610 (void) base_home->ast_accept (this);
3611 this->fill_base_home (result,
3612 node);
3616 void
3617 ifr_adding_visitor::fill_managed_component (
3618 CORBA::ComponentIR::ComponentDef_ptr &result,
3619 AST_Home *node
3622 result = CORBA::ComponentIR::ComponentDef::_nil ();
3623 AST_Component *managed_component = node->managed_component ();
3625 if (managed_component == 0)
3627 return;
3630 CORBA::Contained_var holder =
3631 be_global->repository ()->lookup_id (managed_component->repoID ());
3633 if (!CORBA::is_nil (holder.in ()))
3635 result =
3636 CORBA::ComponentIR::ComponentDef::_narrow (holder.in ());
3638 else
3640 /// Maybe the managed component is in an included IDL file - put it in
3641 /// the repository and go again.
3642 (void) managed_component->ast_accept (this);
3643 this->fill_managed_component (result,
3644 node);
3648 void
3649 ifr_adding_visitor::fill_primary_key (CORBA::ValueDef_ptr &result,
3650 AST_Home *node)
3652 result = CORBA::ValueDef::_nil ();
3653 AST_Type *primary_key = node->primary_key ();
3655 if (primary_key == 0)
3657 return;
3660 CORBA::Contained_var holder =
3661 be_global->repository ()->lookup_id (primary_key->repoID ());
3663 if (!CORBA::is_nil (holder.in ()))
3665 result =
3666 CORBA::ValueDef::_narrow (holder.in ());
3668 else
3670 /// Maybe the primary key is in an included IDL file - put it in
3671 /// the repository and go again.
3672 (void) primary_key->ast_accept (this);
3673 this->fill_primary_key (result,
3674 node);
3678 void
3679 ifr_adding_visitor::fill_abstract_base_values (CORBA::ValueDefSeq &result,
3680 AST_ValueType *node)
3682 CORBA::Long s_length = node->n_inherits ();
3683 result.length (0);
3685 // Not sure if this could be negative in some default case or
3686 // not. If it's 0, we should make the call anyway to clear
3687 // existing entries, if any, from the repository.
3688 if (s_length > 0)
3690 AST_Type **list = node->inherits ();
3691 CORBA::ULong u_length = static_cast<CORBA::ULong> (s_length);
3692 bool first_abs = list[0]->is_abstract ();
3693 result.length (first_abs ? u_length : u_length - 1);
3695 for (CORBA::ULong i = 0; i < u_length; ++i)
3697 if (i == 0 && ! first_abs)
3699 continue;
3702 // Get list[i] into ir_current_.
3703 (void) list[i]->ast_accept (this);
3705 result[first_abs ? i : i - 1] =
3706 CORBA::ValueDef::_narrow (this->ir_current_.in ());
3711 void
3712 ifr_adding_visitor::fill_inherited_interfaces (CORBA::InterfaceDefSeq &result,
3713 AST_Interface *node)
3715 result.length (0);
3716 this->fill_interfaces (result,
3717 node->inherits (),
3718 node->n_inherits ());
3721 void
3722 ifr_adding_visitor::fill_supported_interfaces (CORBA::InterfaceDefSeq &result,
3723 AST_Interface *node)
3725 result.length (0);
3726 CORBA::Long s_length = 0;
3727 AST_Type **list = 0;
3729 switch (node->node_type ())
3731 case AST_Decl::NT_valuetype:
3732 case AST_Decl::NT_eventtype:
3734 AST_ValueType *v = dynamic_cast<AST_ValueType*> (node);
3735 s_length = v->n_supports ();
3736 list = v->supports ();
3737 break;
3739 case AST_Decl::NT_component:
3741 AST_Component *c = dynamic_cast<AST_Component*> (node);
3742 s_length = c->n_supports ();
3743 list = c->supports ();
3744 break;
3746 case AST_Decl::NT_home:
3748 AST_Home *h = dynamic_cast<AST_Home*> (node);
3749 s_length = h->n_supports ();
3750 list = h->supports ();
3751 break;
3753 default:
3754 return;
3757 this->fill_interfaces (result,
3758 list,
3759 s_length);
3762 void
3763 ifr_adding_visitor::fill_interfaces (CORBA::InterfaceDefSeq &result,
3764 AST_Type **list,
3765 CORBA::Long length)
3767 // Not sure if this could be negative in some default case or
3768 // not. If it's 0, we should make the call anyway to clear
3769 // existing entries, if any, from the repository.
3770 if (length > 0)
3772 CORBA::ULong u_length = static_cast<CORBA::ULong> (length);
3773 result.length (u_length);
3775 for (CORBA::ULong i = 0; i < u_length; ++i)
3777 // Get list[i] into ir_current_.
3778 (void) list[i]->ast_accept (this);
3780 result[i] =
3781 CORBA::InterfaceDef::_narrow (this->ir_current_.in ());
3786 void
3787 ifr_adding_visitor::fill_initializers (CORBA::ExtInitializerSeq &result,
3788 AST_ValueType *node)
3790 result.length (0);
3791 AST_Decl *item = 0;
3792 ACE_Vector<AST_Factory *> factories;
3794 for (UTL_ScopeActiveIterator v_iter (node,
3795 UTL_Scope::IK_decls);
3796 !v_iter.is_done ();
3797 v_iter.next ())
3799 item = v_iter.item ();
3801 if (item->node_type () == AST_Decl::NT_factory)
3803 factories.push_back (dynamic_cast<AST_Factory*> (item));
3807 CORBA::ULong n_factories = static_cast<CORBA::ULong> (factories.size ());
3809 if (n_factories == 0)
3811 return;
3814 result.length (n_factories);
3815 CORBA::ULong n_args = 0;
3816 AST_Argument *arg = 0;
3817 CORBA::ULong index = 0;
3818 AST_Exception *excp = 0;
3819 CORBA::Contained_var holder;
3821 for (CORBA::ULong i = 0; i < n_factories; ++i)
3823 result[i].name =
3824 CORBA::string_dup (factories[i]->local_name ()->get_string ());
3825 n_args = static_cast<CORBA::ULong> (factories[i]->argument_count ());
3826 result[i].members.length (n_args);
3828 // The factory should have nothing in its scope but args.
3829 for (UTL_ScopeActiveIterator f_iter (factories[i],
3830 UTL_Scope::IK_decls);
3831 !f_iter.is_done ();
3832 f_iter.next (), ++index)
3834 arg = dynamic_cast<AST_Argument*> (f_iter.item ());
3835 result[i].members[index].name =
3836 CORBA::string_dup (arg->local_name ()->get_string ());
3837 result[i].members[index].type =
3838 CORBA::TypeCode::_duplicate (CORBA::_tc_void);
3840 /// This will put the field type in ir_current_, and also add it
3841 /// to the repository if it's not already there.
3842 if (arg->field_type ()->ast_accept (this) != 0)
3844 ORBSVCS_ERROR ((
3845 LM_ERROR,
3846 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3847 ACE_TEXT ("fill_initializers -")
3848 ACE_TEXT (" failed to accept arg type visitor\n")
3852 result[i].members[index].type_def =
3853 CORBA::IDLType::_duplicate (this->ir_current_.in ());
3856 CORBA::ULong n_exceptions =
3857 static_cast<CORBA::ULong> (factories[i]->n_exceptions ());
3858 result[i].exceptions.length (n_exceptions);
3859 index = 0;
3861 for (UTL_ExceptlistActiveIterator ei (factories[i]->exceptions ());
3862 !ei.is_done ();
3863 ei.next ())
3865 excp = dynamic_cast<AST_Exception*> (ei.item ());
3866 result[i].exceptions[index].name =
3867 CORBA::string_dup (excp->local_name ()->get_string ());
3868 result[i].exceptions[index].id = excp->repoID ();
3869 result[i].exceptions[index].defined_in =
3870 ScopeAsDecl (excp->defined_in ())->repoID ();
3871 result[i].exceptions[index].version = excp->version ();
3872 result[i].exceptions[index++].type =
3873 CORBA::TypeCode::_duplicate (CORBA::_tc_void);
3878 void
3879 ifr_adding_visitor::fill_get_exceptions (CORBA::ExceptionDefSeq &result,
3880 AST_Attribute *node)
3882 this->fill_exceptions (result,
3883 node->get_get_exceptions ());
3886 void
3887 ifr_adding_visitor::fill_set_exceptions (CORBA::ExceptionDefSeq &result,
3888 AST_Attribute *node)
3890 this->fill_exceptions (result,
3891 node->get_set_exceptions ());
3894 void
3895 ifr_adding_visitor::fill_exceptions (CORBA::ExceptionDefSeq &result,
3896 AST_Decl *node)
3898 switch (node->node_type ())
3900 case AST_Decl::NT_op:
3902 AST_Operation *op = dynamic_cast<AST_Operation*> (node);
3903 this->fill_exceptions (result,
3904 op->exceptions ());
3905 return;
3907 case AST_Decl::NT_factory:
3908 case AST_Decl::NT_finder:
3910 AST_Factory *f = dynamic_cast<AST_Factory*> (node);
3911 this->fill_exceptions (result,
3912 f->exceptions ());
3913 return;
3915 default:
3916 result.length (0);
3917 return;
3921 void
3922 ifr_adding_visitor::fill_exceptions (CORBA::ExceptionDefSeq &result,
3923 UTL_ExceptList *list)
3925 if (list == 0)
3927 result.length (0);
3928 return;
3931 result.length (static_cast<CORBA::ULong> (list->length ()));
3932 CORBA::ULong index = 0;
3933 AST_Decl *d = 0;
3934 CORBA::Contained_var holder;
3936 for (UTL_ExceptlistActiveIterator ei (list);
3937 !ei.is_done ();
3938 ei.next (), ++index)
3940 d = ei.item ();
3942 // Just to make sure. The call will return quickly if d has already
3943 // been visited. Can't use ir_current_ because ExceptionDef doesn't
3944 // inherit from IDLType.
3945 (void) d->ast_accept (this);
3947 holder = be_global->repository ()->lookup_id (d->repoID ());
3949 result[index] =
3950 CORBA::ExceptionDef::_narrow (holder.in ());
3954 void
3955 ifr_adding_visitor::fill_params (CORBA::ParDescriptionSeq &result,
3956 UTL_Scope *node)
3958 AST_Argument *arg = 0;
3959 CORBA::ULong n_args = static_cast<CORBA::ULong> (node->nmembers ());
3960 result.length (n_args);
3961 CORBA::ULong index = 0;
3962 CORBA::Contained_var holder;
3964 for (UTL_ScopeActiveIterator iter (node,
3965 UTL_Scope::IK_decls);
3966 ! iter.is_done ();
3967 iter.next (), ++index)
3969 arg = dynamic_cast<AST_Argument*> (iter.item ());
3970 result[index].name =
3971 CORBA::string_dup (arg->local_name ()->get_string ());
3972 result[index].type = CORBA::TypeCode::_duplicate (CORBA::_tc_void);
3974 // Get the arg type into ir_current_.
3975 (void) arg->ast_accept (this);
3977 result[index].type_def =
3978 CORBA::IDLType::_duplicate (this->ir_current_.in ());
3980 result[index].mode = CORBA::PARAM_IN;
3984 void
3985 ifr_adding_visitor::visit_all_factories (AST_Home *node,
3986 CORBA::ComponentIR::HomeDef_ptr h)
3988 CORBA::Contained_var contained;
3989 CORBA::ComponentIR::FactoryDef_var new_def;
3991 for (UTL_ScopeActiveIterator h_iter (node,
3992 UTL_Scope::IK_decls);
3993 !h_iter.is_done ();
3994 h_iter.next ())
3996 AST_Decl *d = h_iter.item ();
3997 AST_Decl::NodeType nt = d->node_type ();
3999 if (nt != AST_Decl::NT_factory)
4001 continue;
4004 AST_Factory *f = dynamic_cast<AST_Factory*> (d);
4006 CORBA::ParDescriptionSeq params;
4007 this->fill_params (params, f);
4009 CORBA::ExceptionDefSeq exceptions;
4010 this->fill_exceptions (exceptions, f);
4012 new_def = h->create_factory (f->repoID (),
4013 f->local_name ()->get_string (),
4014 f->version (),
4015 params,
4016 exceptions);
4020 void
4021 ifr_adding_visitor::visit_all_finders (AST_Home *node,
4022 CORBA::ComponentIR::HomeDef_ptr h)
4024 AST_Finder *f = 0;
4025 CORBA::Contained_var contained;
4026 CORBA::ComponentIR::FinderDef_var new_def;
4028 for (UTL_ScopeActiveIterator h_iter (node,
4029 UTL_Scope::IK_decls);
4030 !h_iter.is_done ();
4031 h_iter.next ())
4033 f = dynamic_cast<AST_Finder*> (h_iter.item ());
4035 if (f == 0)
4037 continue;
4040 CORBA::ParDescriptionSeq params;
4041 this->fill_params (params, f);
4043 CORBA::ExceptionDefSeq exceptions;
4044 this->fill_exceptions (exceptions, f);
4046 new_def = h->create_finder (f->repoID (),
4047 f->local_name ()->get_string (),
4048 f->version (),
4049 params,
4050 exceptions);
4054 void
4055 ifr_adding_visitor::expand_id (ACE_CString &str,
4056 const char *local_name)
4058 ssize_t pos = str.rfind (':');
4059 str = str.substr (0, pos) + '/' + local_name + str.substr (pos);