Merge pull request #1551 from DOCGroup/plm_jira_333
[ACE_TAO.git] / TAO / orbsvcs / IFR_Service / ifr_adding_visitor.cpp
blob057e05a50135c621a57bf5802ae593b6f0467b8c
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 (void)
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_string (AST_String *node)
2307 AST_Expression *ex = node->max_size ();
2309 AST_Expression::AST_ExprValue *ev = ex->ev ();
2311 CORBA::ULong bound = static_cast<CORBA::ULong> (ev->u.ulval);
2315 if (node->node_type () == AST_Decl::NT_string)
2317 this->ir_current_ =
2318 be_global->repository ()->create_string (bound);
2320 else
2322 this->ir_current_ =
2323 be_global->repository ()->create_wstring (bound);
2327 catch (const CORBA::Exception& ex)
2329 ex._tao_print_exception (ACE_TEXT ("visit_string"));
2331 return -1;
2334 return 0;
2338 ifr_adding_visitor::visit_typedef (AST_Typedef *node)
2340 if (node->imported () && !be_global->do_included_files ())
2342 return 0;
2347 this->element_type (node->base_type (), node->owns_base_type ());
2349 CORBA::Container_ptr current_scope =
2350 CORBA::Container::_nil ();
2352 if (be_global->ifr_scopes ().top (current_scope) == 0)
2354 this->ir_current_ =
2355 current_scope->create_alias (
2356 node->repoID (),
2357 node->local_name ()->get_string (),
2358 node->version (),
2359 this->ir_current_.in ()
2362 else
2364 ORBSVCS_ERROR_RETURN ((
2365 LM_ERROR,
2366 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_typedef -")
2367 ACE_TEXT (" scope stack is empty\n")
2373 node->ifr_added (true);
2375 catch (const CORBA::Exception& ex)
2377 if (!this->allow_duplicate_typedefs_)
2379 ex._tao_print_exception (ACE_TEXT ("visit_typedef"));
2381 return -1;
2383 else
2385 ORBSVCS_DEBUG ((LM_DEBUG,
2386 "%s %s\n",
2387 ACE_TEXT ("ifr_adding_visitor::visit_typedef - ignoring duplicate typedef"),
2388 node->local_name ()->get_string ()));
2392 return 0;
2396 ifr_adding_visitor::visit_root (AST_Root *node)
2398 if (be_global->ifr_scopes ().push (be_global->repository ()) != 0)
2400 ORBSVCS_ERROR_RETURN ((
2401 LM_ERROR,
2402 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_root -")
2403 ACE_TEXT (" scope push failed\n")
2409 if (this->visit_scope (node) == -1)
2411 ORBSVCS_ERROR_RETURN ((
2412 LM_ERROR,
2413 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_root -")
2414 ACE_TEXT (" visit_scope failed\n")
2420 CORBA::Container_ptr tmp =
2421 CORBA::Container::_nil ();
2423 if (be_global->ifr_scopes ().pop (tmp) != 0)
2425 ORBSVCS_ERROR_RETURN ((
2426 LM_ERROR,
2427 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_root -")
2428 ACE_TEXT (" scope pop failed\n")
2434 return 0;
2438 ifr_adding_visitor::visit_native (AST_Native *node)
2440 if (node->imported () && !be_global->do_included_files ())
2442 return 0;
2447 CORBA::Contained_var prev_def =
2448 be_global->repository ()->lookup_id (node->repoID ());
2450 if (CORBA::is_nil (prev_def.in ()))
2452 CORBA::Container_ptr current_scope =
2453 CORBA::Container::_nil ();
2455 if (be_global->ifr_scopes ().top (current_scope) == 0)
2457 this->ir_current_ =
2458 current_scope->create_native (
2459 node->repoID (),
2460 node->local_name ()->get_string (),
2461 node->version ()
2464 else
2466 ORBSVCS_ERROR_RETURN ((
2467 LM_ERROR,
2468 ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_native -")
2469 ACE_TEXT (" scope stack is empty\n")
2475 node->ifr_added (true);
2477 else
2479 // If the line below is true, we are clobbering a previous
2480 // entry (from another IDL file) of another type. In that
2481 // case we do what other ORB vendors do, and destroy the
2482 // original entry, create the new one, and let the user beware.
2483 if (!node->ifr_added ())
2485 prev_def->destroy ();
2487 // This call will take the other branch.
2488 return this->visit_native (node);
2491 this->ir_current_ =
2492 CORBA::NativeDef::_narrow (prev_def.in ());
2495 catch (const CORBA::Exception& ex)
2497 ex._tao_print_exception (ACE_TEXT ("visit_native"));
2499 return -1;
2502 return 0;
2505 CORBA::PrimitiveKind
2506 ifr_adding_visitor::expr_type_to_pkind (AST_Expression::ExprType et)
2508 switch (et)
2510 case AST_Expression::EV_short:
2511 return CORBA::pk_short;
2512 case AST_Expression::EV_ushort:
2513 return CORBA::pk_ushort;
2514 case AST_Expression::EV_long:
2515 return CORBA::pk_long;
2516 case AST_Expression::EV_ulong:
2517 return CORBA::pk_ulong;
2518 case AST_Expression::EV_longlong:
2519 return CORBA::pk_longlong;
2520 case AST_Expression::EV_ulonglong:
2521 return CORBA::pk_ulonglong;
2522 case AST_Expression::EV_float:
2523 return CORBA::pk_float;
2524 case AST_Expression::EV_double:
2525 return CORBA::pk_double;
2526 case AST_Expression::EV_longdouble:
2527 return CORBA::pk_longdouble;
2528 case AST_Expression::EV_char:
2529 return CORBA::pk_char;
2530 case AST_Expression::EV_wchar:
2531 return CORBA::pk_wchar;
2532 case AST_Expression::EV_octet:
2533 return CORBA::pk_octet;
2534 case AST_Expression::EV_bool:
2535 return CORBA::pk_boolean;
2536 case AST_Expression::EV_string:
2537 return CORBA::pk_string;
2538 case AST_Expression::EV_wstring:
2539 return CORBA::pk_wstring;
2540 case AST_Expression::EV_any:
2541 return CORBA::pk_any;
2542 case AST_Expression::EV_void:
2543 return CORBA::pk_void;
2544 case AST_Expression::EV_none:
2545 return CORBA::pk_null;
2546 default:
2547 return CORBA::pk_null;
2551 CORBA::PrimitiveKind
2552 ifr_adding_visitor::predefined_type_to_pkind (AST_PredefinedType *node)
2554 switch (node->pt ())
2556 case AST_PredefinedType::PT_short:
2557 return CORBA::pk_short;
2558 case AST_PredefinedType::PT_ushort:
2559 return CORBA::pk_ushort;
2560 case AST_PredefinedType::PT_long:
2561 return CORBA::pk_long;
2562 case AST_PredefinedType::PT_ulong:
2563 return CORBA::pk_ulong;
2564 case AST_PredefinedType::PT_longlong:
2565 return CORBA::pk_longlong;
2566 case AST_PredefinedType::PT_ulonglong:
2567 return CORBA::pk_ulonglong;
2568 case AST_PredefinedType::PT_float:
2569 return CORBA::pk_float;
2570 case AST_PredefinedType::PT_double:
2571 return CORBA::pk_double;
2572 case AST_PredefinedType::PT_longdouble:
2573 return CORBA::pk_longdouble;
2574 case AST_PredefinedType::PT_char:
2575 return CORBA::pk_char;
2576 case AST_PredefinedType::PT_wchar:
2577 return CORBA::pk_wchar;
2578 case AST_PredefinedType::PT_octet:
2579 return CORBA::pk_octet;
2580 case AST_PredefinedType::PT_boolean:
2581 return CORBA::pk_boolean;
2582 case AST_PredefinedType::PT_any:
2583 return CORBA::pk_any;
2584 case AST_PredefinedType::PT_void:
2585 return CORBA::pk_void;
2586 case AST_PredefinedType::PT_object:
2587 return CORBA::pk_objref;
2588 case AST_PredefinedType::PT_value:
2589 return CORBA::pk_value_base;
2590 case AST_PredefinedType::PT_pseudo:
2592 const char *local_name = node->local_name ()->get_string ();
2594 if (!ACE_OS::strcmp (local_name, "Principal"))
2596 return CORBA::pk_Principal;
2598 else
2600 return CORBA::pk_TypeCode;
2603 default:
2604 return CORBA::pk_null;
2608 void
2609 ifr_adding_visitor::load_any (AST_Expression::AST_ExprValue *ev,
2610 CORBA::Any &any)
2612 switch (ev->et)
2614 case AST_Expression::EV_short:
2615 any <<= ev->u.sval;
2616 break;
2617 case AST_Expression::EV_ushort:
2618 any <<= ev->u.usval;
2619 break;
2620 case AST_Expression::EV_long:
2621 any <<= static_cast<CORBA::Long> (ev->u.lval);
2622 break;
2623 case AST_Expression::EV_ulong:
2624 any <<= static_cast<CORBA::ULong> (ev->u.ulval);
2625 break;
2626 case AST_Expression::EV_longlong:
2627 any <<= ev->u.llval;
2628 break;
2629 case AST_Expression::EV_ulonglong:
2630 any <<= ev->u.ullval;
2631 break;
2632 case AST_Expression::EV_float:
2633 any <<= ev->u.fval;
2634 break;
2635 case AST_Expression::EV_double:
2636 any <<= ev->u.dval;
2637 break;
2638 #if 0
2639 case AST_Expression::EV_longdouble:
2640 // Not implemented in IDL compiler.
2641 #endif
2642 case AST_Expression::EV_char:
2643 any <<= CORBA::Any::from_char (ev->u.cval);
2644 break;
2645 case AST_Expression::EV_wchar:
2646 any <<= CORBA::Any::from_wchar (ev->u.wcval);
2647 break;
2648 case AST_Expression::EV_octet:
2649 any <<= CORBA::Any::from_octet (ev->u.oval);
2650 break;
2651 case AST_Expression::EV_bool:
2652 any <<= CORBA::Any::from_boolean ((CORBA::Boolean) ev->u.bval);
2653 break;
2654 case AST_Expression::EV_string:
2655 any <<= ev->u.strval->get_string ();
2656 break;
2657 case AST_Expression::EV_wstring:
2659 char *str = ev->u.wstrval;
2660 size_t len = ACE_OS::strlen (str);
2661 CORBA::WChar *wstr = 0;
2662 ACE_NEW (wstr,
2663 CORBA::WChar[len + 1]);
2665 for (size_t i = 0; i < len; ++i)
2667 wstr[i] = static_cast<CORBA::WChar> (str[i]);
2670 wstr[len] = 0;
2671 any <<= wstr;
2672 delete [] wstr;
2673 break;
2675 case AST_Expression::EV_enum:
2676 any <<= static_cast<CORBA::ULong> (ev->u.eval);
2677 break;
2678 default:
2679 break;
2683 void
2684 ifr_adding_visitor::element_type (AST_Type *base_type, bool owned)
2686 AST_Decl::NodeType nt = base_type->node_type ();
2687 bool no_repo_id = nt == AST_Decl::NT_array
2688 || nt == AST_Decl::NT_sequence
2689 || base_type->anonymous ();
2691 if (no_repo_id || owned)
2693 if (base_type->ast_accept (this) == -1)
2695 ORBSVCS_ERROR ((
2696 LM_ERROR,
2697 ACE_TEXT ("(%N:%l) ifr_adding_visitor::element_type -")
2698 ACE_TEXT (" failed to accept visitor\n")
2701 throw Bailout ();
2704 else
2706 CORBA::Contained_var contained =
2707 be_global->repository ()->lookup_id (base_type->repoID ());
2709 if (CORBA::is_nil (contained.in ()))
2711 ORBSVCS_ERROR ((
2712 LM_ERROR,
2713 ACE_TEXT ("(%N:%l) ifr_adding_visitor::element_type -")
2714 ACE_TEXT (" lookup_id failed\n")
2717 throw Bailout ();
2720 this->ir_current_ = CORBA::IDLType::_narrow (contained.in ());
2725 ifr_adding_visitor::create_interface_def (AST_Interface *node)
2727 CORBA::ULong n_parents = static_cast<CORBA::ULong> (node->n_inherits ());
2728 AST_Type **parents = node->inherits ();
2729 CORBA::Contained_var result;
2730 CORBA::AbstractInterfaceDefSeq abs_bases;
2731 CORBA::InterfaceDefSeq bases;
2733 if (node->is_abstract ())
2735 abs_bases.length (n_parents);
2737 // Construct a list of the parents.
2738 for (CORBA::ULong i = 0; i < n_parents; ++i)
2740 AST_Interface *intf =
2741 dynamic_cast<AST_Interface*> (parents[i]);
2743 if (intf == 0)
2745 ORBSVCS_ERROR_RETURN ((
2746 LM_ERROR,
2747 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2748 ACE_TEXT ("create_interface_def -")
2749 ACE_TEXT (" parent %s is not an interface\n"),
2750 parents[i]->full_name ()),
2751 -1);
2754 result =
2755 be_global->repository ()->lookup_id (intf->repoID ());
2757 // If we got to visit_interface() from a forward declared interface,
2758 // this node may not yet be in the repository.
2759 if (CORBA::is_nil (result.in ()))
2761 int status = this->create_interface_def (intf);
2763 if (status != 0)
2765 ORBSVCS_ERROR_RETURN ((
2766 LM_ERROR,
2767 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2768 ACE_TEXT ("create_interface_def -")
2769 ACE_TEXT (" parent interfacedef creation failed\n")),
2770 -1);
2773 bases[i] =
2774 CORBA::AbstractInterfaceDef::_narrow (this->ir_current_.in ());
2776 else
2778 abs_bases[i] =
2779 CORBA::AbstractInterfaceDef::_narrow (result.in ());
2782 if (CORBA::is_nil (abs_bases[i]))
2784 ORBSVCS_ERROR_RETURN ((
2785 LM_ERROR,
2786 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2787 ACE_TEXT ("create_interface_def -")
2788 ACE_TEXT (" CORBA::InterfaceDef::_narrow failed\n")
2795 else
2797 bases.length (n_parents);
2799 // Construct a list of the parents.
2800 for (CORBA::ULong i = 0; i < n_parents; ++i)
2802 AST_Interface *intf =
2803 dynamic_cast<AST_Interface*> (parents[i]);
2805 if (intf == 0)
2807 ORBSVCS_ERROR_RETURN ((
2808 LM_ERROR,
2809 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2810 ACE_TEXT ("create_interface_def -")
2811 ACE_TEXT (" parent %s is not an interface\n"),
2812 parents[i]->full_name ()),
2813 -1);
2816 result =
2817 be_global->repository ()->lookup_id (intf->repoID ());
2819 // If we got to visit_interface() from a forward declared interface,
2820 // this node may not yet be in the repository.
2821 if (CORBA::is_nil (result.in ()))
2823 int status = this->create_interface_def (intf);
2825 if (status != 0)
2827 ORBSVCS_ERROR_RETURN ((
2828 LM_ERROR,
2829 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2830 ACE_TEXT ("create_interface_def -")
2831 ACE_TEXT (" parent interfacedef creation failed\n")
2837 bases[i] = CORBA::InterfaceDef::_narrow (this->ir_current_.in ());
2839 else
2841 bases[i] = CORBA::InterfaceDef::_narrow (result.in ());
2844 if (CORBA::is_nil (bases[i]))
2846 ORBSVCS_ERROR_RETURN ((
2847 LM_ERROR,
2848 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2849 ACE_TEXT ("create_interface_def -")
2850 ACE_TEXT (" CORBA::InterfaceDef::_narrow failed\n")
2858 CORBA::Container_ptr current_scope =
2859 CORBA::Container::_nil ();
2861 if (be_global->ifr_scopes ().top (current_scope) == 0)
2863 CORBA::InterfaceDef_var new_def;
2865 if (node->is_local ())
2867 new_def =
2868 current_scope->create_local_interface (
2869 node->repoID (),
2870 node->local_name ()->get_string (),
2871 node->version (),
2872 bases
2875 else if (node->is_abstract ())
2877 new_def =
2878 current_scope->create_abstract_interface (
2879 node->repoID (),
2880 node->local_name ()->get_string (),
2881 node->version (),
2882 abs_bases
2885 else
2887 new_def =
2888 current_scope->create_interface (
2889 node->repoID (),
2890 node->local_name ()->get_string (),
2891 node->version (),
2892 bases
2897 node->ifr_added (true);
2899 // Push the new IR object onto the scope stack.
2900 CORBA::Container_var new_scope =
2901 CORBA::Container::_narrow (new_def.in ());
2903 if (be_global->ifr_scopes ().push (new_scope.in ()) != 0)
2905 ORBSVCS_ERROR_RETURN ((
2906 LM_ERROR,
2907 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2908 ACE_TEXT ("create_interface_def -")
2909 ACE_TEXT (" scope push failed\n")
2915 // Visit the members, if any.
2916 if (this->visit_scope (node) == -1)
2918 ORBSVCS_ERROR_RETURN ((
2919 LM_ERROR,
2920 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2921 ACE_TEXT ("create_interface_def -")
2922 ACE_TEXT (" visit_scope failed\n")
2928 // This spot in the AST doesn't necessarily have to be the
2929 // interface definition - it could be any reference to it.
2930 // The front end will already have fully defined it, so all
2931 // the info is available anywhere. So it's a good idea to
2932 // update the current IR object holder now. This will
2933 // consume the objref pointer.
2934 this->ir_current_ =
2935 CORBA::IDLType::_duplicate (new_def.in ());
2937 CORBA::Container_ptr used_scope =
2938 CORBA::Container::_nil ();
2940 // Pop the new IR object back off the scope stack.
2941 if (be_global->ifr_scopes ().pop (used_scope) != 0)
2943 ORBSVCS_ERROR_RETURN ((
2944 LM_ERROR,
2945 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
2946 ACE_TEXT ("create_interface_def -")
2947 ACE_TEXT (" scope pop failed\n")
2953 else
2955 ORBSVCS_ERROR_RETURN ((
2956 LM_ERROR,
2957 ACE_TEXT ("(%N:%l) ifr_adding_visitor::create_interface_def -")
2958 ACE_TEXT (" scope stack is empty\n")
2964 return 0;
2968 ifr_adding_visitor::create_value_def (AST_ValueType *node)
2970 CORBA::Container_ptr current_scope =
2971 CORBA::Container::_nil ();
2973 if (be_global->ifr_scopes ().top (current_scope) == 0)
2975 CORBA::ValueDef_var base_value;
2976 this->fill_base_value (base_value.out (),
2977 node);
2979 CORBA::ValueDefSeq abstract_base_values;
2980 this->fill_abstract_base_values (abstract_base_values,
2981 node);
2983 CORBA::InterfaceDefSeq supported_interfaces;
2984 this->fill_supported_interfaces (supported_interfaces,
2985 node);
2987 CORBA::ExtInitializerSeq initializers;
2988 this->fill_initializers (initializers,
2989 node);
2991 CORBA::ExtValueDef_var new_def =
2992 current_scope->create_ext_value (
2993 node->repoID (),
2994 node->local_name ()->get_string (),
2995 node->version (),
2996 static_cast<CORBA::Boolean> (node->custom ()),
2997 static_cast<CORBA::Boolean> (node->is_abstract ()),
2998 base_value.in (),
2999 static_cast<CORBA::Boolean> (node->truncatable ()),
3000 abstract_base_values,
3001 supported_interfaces,
3002 initializers
3005 node->ifr_added (true);
3007 // Push the new IR object onto the scope stack.
3008 CORBA::Container_var new_scope =
3009 CORBA::Container::_narrow (new_def.in ());
3011 if (be_global->ifr_scopes ().push (new_scope.in ()) != 0)
3013 ORBSVCS_ERROR_RETURN ((
3014 LM_ERROR,
3015 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3016 ACE_TEXT ("create_value_def -")
3017 ACE_TEXT (" scope push failed\n")
3023 // Visit the members, if any.
3024 if (this->visit_scope (node) == -1)
3026 ORBSVCS_ERROR_RETURN ((
3027 LM_ERROR,
3028 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3029 ACE_TEXT ("create_value_def -")
3030 ACE_TEXT (" visit_scope failed\n")
3036 // This spot in the AST doesn't necessarily have to be the
3037 // interface definition - it could be any reference to it.
3038 // The front end will already have fully defined it, so all
3039 // the info is available anywhere. So it's a good idea to
3040 // update the current IR object holder now. This will
3041 // consume the objref pointer.
3042 this->ir_current_ =
3043 CORBA::IDLType::_duplicate (new_def.in ());
3045 CORBA::Container_ptr used_scope =
3046 CORBA::Container::_nil ();
3048 // Pop the new IR object back off the scope stack.
3049 if (be_global->ifr_scopes ().pop (used_scope) != 0)
3051 ORBSVCS_ERROR_RETURN ((
3052 LM_ERROR,
3053 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3054 ACE_TEXT ("create_value_def -")
3055 ACE_TEXT (" scope pop failed\n")
3061 else
3063 ORBSVCS_ERROR_RETURN ((
3064 LM_ERROR,
3065 ACE_TEXT ("(%N:%l) ifr_adding_visitor::create_value_def -")
3066 ACE_TEXT (" scope stack is empty\n")
3072 return 0;
3076 ifr_adding_visitor::create_component_def (AST_Component *node)
3078 CORBA::Container_ptr current_scope =
3079 CORBA::Container::_nil ();
3081 if (be_global->ifr_scopes ().top (current_scope) == 0)
3083 CORBA::ComponentIR::ComponentDef_var base_component;
3084 this->fill_base_component (base_component.out (),
3085 node);
3087 CORBA::InterfaceDefSeq supported_interfaces;
3088 this->fill_supported_interfaces (supported_interfaces,
3089 node);
3091 CORBA::ComponentIR::Container_var ccm_scope =
3092 CORBA::ComponentIR::Container::_narrow (current_scope);
3094 CORBA::ComponentIR::ComponentDef_var new_def =
3095 ccm_scope->create_component (node->repoID (),
3096 node->local_name ()->get_string (),
3097 node->version (),
3098 base_component.in (),
3099 supported_interfaces);
3101 node->ifr_added (true);
3103 if (be_global->ifr_scopes ().push (new_def.in ()) != 0)
3105 ORBSVCS_ERROR_RETURN ((
3106 LM_ERROR,
3107 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3108 ACE_TEXT ("create_component_def -")
3109 ACE_TEXT (" scope push failed\n")
3115 // This spot in the AST doesn't necessarily have to be the
3116 // interface definition - it could be any reference to it.
3117 // The front end will already have fully defined it, so all
3118 // the info is available anywhere. So it's a good idea to
3119 // update the current IR object holder now. This will
3120 // consume the objref pointer.
3121 this->ir_current_ =
3122 CORBA::IDLType::_duplicate (new_def.in ());
3124 // Visit the members, if any.
3125 if (this->visit_scope (node) == -1)
3127 ORBSVCS_ERROR_RETURN ((
3128 LM_ERROR,
3129 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3130 ACE_TEXT ("create_component_def -")
3131 ACE_TEXT (" visit_scope failed\n")
3137 CORBA::Container_ptr used_scope =
3138 CORBA::Container::_nil ();
3140 // Pop the new IR object back off the scope stack.
3141 if (be_global->ifr_scopes ().pop (used_scope) != 0)
3143 ORBSVCS_ERROR_RETURN ((
3144 LM_ERROR,
3145 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3146 ACE_TEXT ("create_component_def -")
3147 ACE_TEXT (" scope pop failed\n")
3153 else
3155 ORBSVCS_ERROR_RETURN ((
3156 LM_ERROR,
3157 ACE_TEXT ("(%N:%l) ifr_adding_visitor::create_component_def -")
3158 ACE_TEXT (" scope stack is empty\n")
3164 return 0;
3168 ifr_adding_visitor::create_home_def (AST_Home *node)
3170 CORBA::Container_ptr current_scope =
3171 CORBA::Container::_nil ();
3173 if (be_global->ifr_scopes ().top (current_scope) == 0)
3175 CORBA::ComponentIR::HomeDef_var base_home;
3176 this->fill_base_home (base_home.out (),
3177 node);
3179 CORBA::ComponentIR::ComponentDef_var managed_component;
3180 this->fill_managed_component (managed_component.out (),
3181 node);
3183 CORBA::InterfaceDefSeq supported_interfaces;
3184 this->fill_supported_interfaces (supported_interfaces,
3185 node);
3187 CORBA::ValueDef_var primary_key;
3188 this->fill_primary_key (primary_key.out (),
3189 node);
3191 CORBA::ComponentIR::Container_var ccm_scope =
3192 CORBA::ComponentIR::Container::_narrow (current_scope);
3194 CORBA::ComponentIR::HomeDef_var new_def =
3195 ccm_scope->create_home (node->repoID (),
3196 node->local_name ()->get_string (),
3197 node->version (),
3198 base_home.in (),
3199 managed_component.in (),
3200 supported_interfaces,
3201 primary_key.in ());
3203 node->ifr_added (true);
3205 // Push the new IR object onto the scope stack.
3206 CORBA::Container_var new_scope =
3207 CORBA::Container::_narrow (new_def.in ());
3209 if (be_global->ifr_scopes ().push (new_scope.in ()) != 0)
3211 ORBSVCS_ERROR_RETURN ((
3212 LM_ERROR,
3213 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3214 ACE_TEXT ("create_home_def -")
3215 ACE_TEXT (" scope push failed\n")
3221 // Visit the members, if any.
3222 if (this->visit_scope (node) == -1)
3224 ORBSVCS_ERROR_RETURN ((
3225 LM_ERROR,
3226 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3227 ACE_TEXT ("create_home_def -")
3228 ACE_TEXT (" visit_scope failed\n")
3234 // Get the contents of these lists into the repository.
3236 this->visit_all_factories (node,
3237 new_def.in ());
3239 this->visit_all_finders (node,
3240 new_def.in ());
3242 // This spot in the AST doesn't necessarily have to be the
3243 // interface definition - it could be any reference to it.
3244 // The front end will already have fully defined it, so all
3245 // the info is available anywhere. So it's a good idea to
3246 // update the current IR object holder now. This will
3247 // consume the objref pointer.
3248 this->ir_current_ =
3249 CORBA::IDLType::_duplicate (new_def.in ());
3251 CORBA::Container_ptr used_scope =
3252 CORBA::Container::_nil ();
3254 // Pop the new IR object back off the scope stack.
3255 if (be_global->ifr_scopes ().pop (used_scope) != 0)
3257 ORBSVCS_ERROR_RETURN ((
3258 LM_ERROR,
3259 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3260 ACE_TEXT ("create_home_def -")
3261 ACE_TEXT (" scope pop failed\n")
3267 else
3269 ORBSVCS_ERROR_RETURN ((
3270 LM_ERROR,
3271 ACE_TEXT ("(%N:%l) ifr_adding_visitor::create_home_def -")
3272 ACE_TEXT (" scope stack is empty\n")
3278 return 0;
3282 ifr_adding_visitor::create_event_def (AST_EventType *node)
3284 CORBA::Container_ptr current_scope =
3285 CORBA::Container::_nil ();
3287 if (be_global->ifr_scopes ().top (current_scope) == 0)
3289 CORBA::ValueDef_var base_value;
3290 this->fill_base_value (base_value.out (),
3291 node);
3293 CORBA::ValueDefSeq abstract_base_values;
3294 this->fill_abstract_base_values (abstract_base_values,
3295 node);
3297 CORBA::InterfaceDefSeq supported_interfaces;
3298 this->fill_supported_interfaces (supported_interfaces,
3299 node);
3301 CORBA::ExtInitializerSeq initializers;
3302 this->fill_initializers (initializers,
3303 node);
3305 CORBA::ComponentIR::Container_var ccm_scope =
3306 CORBA::ComponentIR::Container::_narrow (current_scope);
3308 CORBA::ExtValueDef_var new_def =
3309 ccm_scope->create_event (
3310 node->repoID (),
3311 node->local_name ()->get_string (),
3312 node->version (),
3313 static_cast<CORBA::Boolean> (node->custom ()),
3314 static_cast<CORBA::Boolean> (node->is_abstract ()),
3315 base_value.in (),
3316 static_cast<CORBA::Boolean> (node->truncatable ()),
3317 abstract_base_values,
3318 supported_interfaces,
3319 initializers
3322 node->ifr_added (true);
3324 // Push the new IR object onto the scope stack.
3325 CORBA::Container_var new_scope =
3326 CORBA::Container::_narrow (new_def.in ());
3328 if (be_global->ifr_scopes ().push (new_scope.in ()) != 0)
3330 ORBSVCS_ERROR_RETURN ((
3331 LM_ERROR,
3332 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3333 ACE_TEXT ("create_event_def -")
3334 ACE_TEXT (" scope push failed\n")
3340 // Visit the members, if any.
3341 if (this->visit_scope (node) == -1)
3343 ORBSVCS_ERROR_RETURN ((
3344 LM_ERROR,
3345 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3346 ACE_TEXT ("create_event_def -")
3347 ACE_TEXT (" visit_scope failed\n")
3353 // This spot in the AST doesn't necessarily have to be the
3354 // interface definition - it could be any reference to it.
3355 // The front end will already have fully defined it, so all
3356 // the info is available anywhere. So it's a good idea to
3357 // update the current IR object holder now. This will
3358 // consume the objref pointer.
3359 this->ir_current_ =
3360 CORBA::IDLType::_duplicate (new_def.in ());
3362 CORBA::Container_ptr used_scope =
3363 CORBA::Container::_nil ();
3365 // Pop the new IR object back off the scope stack.
3366 if (be_global->ifr_scopes ().pop (used_scope) != 0)
3368 ORBSVCS_ERROR_RETURN ((
3369 LM_ERROR,
3370 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3371 ACE_TEXT ("create_event_def -")
3372 ACE_TEXT (" scope pop failed\n")
3378 else
3380 ORBSVCS_ERROR_RETURN ((
3381 LM_ERROR,
3382 ACE_TEXT ("(%N:%l) ifr_adding_visitor::create_event_def -")
3383 ACE_TEXT (" scope stack is empty\n")
3389 return 0;
3393 ifr_adding_visitor::create_value_member (AST_Field *node)
3397 AST_Type *bt = node->field_type ();
3398 AST_Decl::NodeType nt = bt->node_type ();
3400 // We can't use lookup_id() on these, because
3401 // they don't inherit from Contained.
3402 if (nt == AST_Decl::NT_pre_defined
3403 || nt == AST_Decl::NT_string
3404 || nt == AST_Decl::NT_wstring
3405 || nt == AST_Decl::NT_array
3406 || nt == AST_Decl::NT_sequence)
3408 /// This will put the repo entry into ir_current_.
3409 if (bt->ast_accept (this) != 0)
3411 ORBSVCS_ERROR_RETURN ((
3412 LM_ERROR,
3413 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3414 ACE_TEXT ("create_value_member -")
3415 ACE_TEXT (" visit base type failed\n")
3421 else
3423 // If the IDL is legal, this will succeed.
3424 CORBA::Contained_var holder =
3425 be_global->repository ()->lookup_id (bt->repoID ());
3427 this->ir_current_ =
3428 CORBA::IDLType::_narrow (holder.in ());
3431 CORBA::Visibility vis = CORBA::PUBLIC_MEMBER;
3433 switch (node->visibility ())
3435 case AST_Field::vis_PUBLIC:
3436 break;
3437 case AST_Field::vis_PRIVATE:
3438 vis = CORBA::PRIVATE_MEMBER;
3439 break;
3440 default:
3441 ORBSVCS_ERROR_RETURN ((
3442 LM_ERROR,
3443 ACE_TEXT ("(%N:%l) ifr_adding_visitor::create_value_member -")
3444 ACE_TEXT (" bad visibility value in node\n")
3450 CORBA::Container_ptr current_scope = CORBA::Container::_nil ();
3452 if (be_global->ifr_scopes ().top (current_scope) != 0)
3454 ORBSVCS_ERROR_RETURN ((
3455 LM_ERROR,
3456 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3457 ACE_TEXT ("create_value_member -")
3458 ACE_TEXT (" scope stack empty\n")
3464 CORBA::ValueDef_var vt =
3465 CORBA::ValueDef::_narrow (current_scope);
3467 CORBA::ValueMemberDef_var vm =
3468 vt->create_value_member (node->repoID (),
3469 node->local_name ()->get_string (),
3470 node->version (),
3471 this->ir_current_.in (),
3472 vis);
3474 catch (const CORBA::Exception& ex)
3476 ex._tao_print_exception (ACE_TEXT ("create_value_member"));
3478 return -1;
3481 return 0;
3484 void
3485 ifr_adding_visitor::get_referenced_type (AST_Type *node)
3487 switch (node->node_type ())
3489 // For anonymous types, a new IR object is be created each
3490 // time, so we just visit the node, which get the object and
3491 // updates ir_current_.
3492 case AST_Decl::NT_pre_defined:
3493 case AST_Decl::NT_string:
3494 case AST_Decl::NT_wstring:
3495 case AST_Decl::NT_array:
3496 case AST_Decl::NT_sequence:
3497 if (node->ast_accept (this) == -1)
3499 ORBSVCS_ERROR ((
3500 LM_ERROR,
3501 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3502 ACE_TEXT ("get_scope_member -")
3503 ACE_TEXT (" failed to accept visitor\n")
3507 break;
3508 // For names types, we can just look up the entry and update
3509 // ir_current_.
3510 default:
3512 CORBA::Contained_var prev_def =
3513 be_global->repository ()->lookup_id (node->repoID ());
3515 this->ir_current_ =
3516 CORBA::IDLType::_narrow (prev_def.in ());
3517 break;
3522 void
3523 ifr_adding_visitor::fill_base_value (CORBA::ValueDef_ptr &result,
3524 AST_ValueType *node)
3526 result = CORBA::ValueDef::_nil ();
3527 AST_Type *base_value = node->inherits_concrete ();
3529 if (base_value == 0)
3531 return;
3534 CORBA::Contained_var holder =
3535 be_global->repository ()->lookup_id (
3536 base_value->repoID ()
3539 if (!CORBA::is_nil (holder.in ()))
3541 result =
3542 CORBA::ValueDef::_narrow (holder.in ());
3546 void
3547 ifr_adding_visitor::fill_base_component (
3548 CORBA::ComponentIR::ComponentDef_ptr &result,
3549 AST_Component *node
3552 result = CORBA::ComponentIR::ComponentDef::_nil ();
3553 AST_Component *base_component = node->base_component ();
3555 if (base_component == 0)
3557 return;
3560 CORBA::Contained_var holder =
3561 be_global->repository ()->lookup_id (
3562 base_component->repoID ()
3565 if (!CORBA::is_nil (holder.in ()))
3567 result =
3568 CORBA::ComponentIR::ComponentDef::_narrow (holder.in ());
3572 void
3573 ifr_adding_visitor::fill_base_home (CORBA::ComponentIR::HomeDef_ptr &result,
3574 AST_Home *node)
3576 result = CORBA::ComponentIR::HomeDef::_nil ();
3577 AST_Home *base_home = node->base_home ();
3579 if (base_home == 0)
3581 return;
3584 CORBA::Contained_var holder =
3585 be_global->repository ()->lookup_id (
3586 base_home->repoID ()
3589 if (!CORBA::is_nil (holder.in ()))
3591 result =
3592 CORBA::ComponentIR::HomeDef::_narrow (holder.in ());
3594 else
3596 /// Maybe the base home is in an included IDL file - put it in
3597 /// the repository and go again.
3598 (void) base_home->ast_accept (this);
3599 this->fill_base_home (result,
3600 node);
3604 void
3605 ifr_adding_visitor::fill_managed_component (
3606 CORBA::ComponentIR::ComponentDef_ptr &result,
3607 AST_Home *node
3610 result = CORBA::ComponentIR::ComponentDef::_nil ();
3611 AST_Component *managed_component = node->managed_component ();
3613 if (managed_component == 0)
3615 return;
3618 CORBA::Contained_var holder =
3619 be_global->repository ()->lookup_id (managed_component->repoID ());
3621 if (!CORBA::is_nil (holder.in ()))
3623 result =
3624 CORBA::ComponentIR::ComponentDef::_narrow (holder.in ());
3626 else
3628 /// Maybe the managed component is in an included IDL file - put it in
3629 /// the repository and go again.
3630 (void) managed_component->ast_accept (this);
3631 this->fill_managed_component (result,
3632 node);
3636 void
3637 ifr_adding_visitor::fill_primary_key (CORBA::ValueDef_ptr &result,
3638 AST_Home *node)
3640 result = CORBA::ValueDef::_nil ();
3641 AST_Type *primary_key = node->primary_key ();
3643 if (primary_key == 0)
3645 return;
3648 CORBA::Contained_var holder =
3649 be_global->repository ()->lookup_id (primary_key->repoID ());
3651 if (!CORBA::is_nil (holder.in ()))
3653 result =
3654 CORBA::ValueDef::_narrow (holder.in ());
3656 else
3658 /// Maybe the primary key is in an included IDL file - put it in
3659 /// the repository and go again.
3660 (void) primary_key->ast_accept (this);
3661 this->fill_primary_key (result,
3662 node);
3666 void
3667 ifr_adding_visitor::fill_abstract_base_values (CORBA::ValueDefSeq &result,
3668 AST_ValueType *node)
3670 CORBA::Long s_length = node->n_inherits ();
3671 result.length (0);
3673 // Not sure if this could be negative in some default case or
3674 // not. If it's 0, we should make the call anyway to clear
3675 // existing entries, if any, from the repository.
3676 if (s_length > 0)
3678 AST_Type **list = node->inherits ();
3679 CORBA::ULong u_length = static_cast<CORBA::ULong> (s_length);
3680 bool first_abs = list[0]->is_abstract ();
3681 result.length (first_abs ? u_length : u_length - 1);
3683 for (CORBA::ULong i = 0; i < u_length; ++i)
3685 if (i == 0 && ! first_abs)
3687 continue;
3690 // Get list[i] into ir_current_.
3691 (void) list[i]->ast_accept (this);
3693 result[first_abs ? i : i - 1] =
3694 CORBA::ValueDef::_narrow (this->ir_current_.in ());
3699 void
3700 ifr_adding_visitor::fill_inherited_interfaces (CORBA::InterfaceDefSeq &result,
3701 AST_Interface *node)
3703 result.length (0);
3704 this->fill_interfaces (result,
3705 node->inherits (),
3706 node->n_inherits ());
3709 void
3710 ifr_adding_visitor::fill_supported_interfaces (CORBA::InterfaceDefSeq &result,
3711 AST_Interface *node)
3713 result.length (0);
3714 CORBA::Long s_length = 0;
3715 AST_Type **list = 0;
3717 switch (node->node_type ())
3719 case AST_Decl::NT_valuetype:
3720 case AST_Decl::NT_eventtype:
3722 AST_ValueType *v = dynamic_cast<AST_ValueType*> (node);
3723 s_length = v->n_supports ();
3724 list = v->supports ();
3725 break;
3727 case AST_Decl::NT_component:
3729 AST_Component *c = dynamic_cast<AST_Component*> (node);
3730 s_length = c->n_supports ();
3731 list = c->supports ();
3732 break;
3734 case AST_Decl::NT_home:
3736 AST_Home *h = dynamic_cast<AST_Home*> (node);
3737 s_length = h->n_supports ();
3738 list = h->supports ();
3739 break;
3741 default:
3742 return;
3745 this->fill_interfaces (result,
3746 list,
3747 s_length);
3750 void
3751 ifr_adding_visitor::fill_interfaces (CORBA::InterfaceDefSeq &result,
3752 AST_Type **list,
3753 CORBA::Long length)
3755 // Not sure if this could be negative in some default case or
3756 // not. If it's 0, we should make the call anyway to clear
3757 // existing entries, if any, from the repository.
3758 if (length > 0)
3760 CORBA::ULong u_length = static_cast<CORBA::ULong> (length);
3761 result.length (u_length);
3763 for (CORBA::ULong i = 0; i < u_length; ++i)
3765 // Get list[i] into ir_current_.
3766 (void) list[i]->ast_accept (this);
3768 result[i] =
3769 CORBA::InterfaceDef::_narrow (this->ir_current_.in ());
3774 void
3775 ifr_adding_visitor::fill_initializers (CORBA::ExtInitializerSeq &result,
3776 AST_ValueType *node)
3778 result.length (0);
3779 AST_Decl *item = 0;
3780 ACE_Vector<AST_Factory *> factories;
3782 for (UTL_ScopeActiveIterator v_iter (node,
3783 UTL_Scope::IK_decls);
3784 !v_iter.is_done ();
3785 v_iter.next ())
3787 item = v_iter.item ();
3789 if (item->node_type () == AST_Decl::NT_factory)
3791 factories.push_back (dynamic_cast<AST_Factory*> (item));
3795 CORBA::ULong n_factories = static_cast<CORBA::ULong> (factories.size ());
3797 if (n_factories == 0)
3799 return;
3802 result.length (n_factories);
3803 CORBA::ULong n_args = 0;
3804 AST_Argument *arg = 0;
3805 CORBA::ULong index = 0;
3806 AST_Exception *excp = 0;
3807 CORBA::Contained_var holder;
3809 for (CORBA::ULong i = 0; i < n_factories; ++i)
3811 result[i].name =
3812 CORBA::string_dup (factories[i]->local_name ()->get_string ());
3813 n_args = static_cast<CORBA::ULong> (factories[i]->argument_count ());
3814 result[i].members.length (n_args);
3816 // The factory should have nothing in its scope but args.
3817 for (UTL_ScopeActiveIterator f_iter (factories[i],
3818 UTL_Scope::IK_decls);
3819 !f_iter.is_done ();
3820 f_iter.next (), ++index)
3822 arg = dynamic_cast<AST_Argument*> (f_iter.item ());
3823 result[i].members[index].name =
3824 CORBA::string_dup (arg->local_name ()->get_string ());
3825 result[i].members[index].type =
3826 CORBA::TypeCode::_duplicate (CORBA::_tc_void);
3828 /// This will put the field type in ir_current_, and also add it
3829 /// to the repository if it's not already there.
3830 if (arg->field_type ()->ast_accept (this) != 0)
3832 ORBSVCS_ERROR ((
3833 LM_ERROR,
3834 ACE_TEXT ("(%N:%l) ifr_adding_visitor::")
3835 ACE_TEXT ("fill_initializers -")
3836 ACE_TEXT (" failed to accept arg type visitor\n")
3840 result[i].members[index].type_def =
3841 CORBA::IDLType::_duplicate (this->ir_current_.in ());
3844 CORBA::ULong n_exceptions =
3845 static_cast<CORBA::ULong> (factories[i]->n_exceptions ());
3846 result[i].exceptions.length (n_exceptions);
3847 index = 0;
3849 for (UTL_ExceptlistActiveIterator ei (factories[i]->exceptions ());
3850 !ei.is_done ();
3851 ei.next ())
3853 excp = dynamic_cast<AST_Exception*> (ei.item ());
3854 result[i].exceptions[index].name =
3855 CORBA::string_dup (excp->local_name ()->get_string ());
3856 result[i].exceptions[index].id = excp->repoID ();
3857 result[i].exceptions[index].defined_in =
3858 ScopeAsDecl (excp->defined_in ())->repoID ();
3859 result[i].exceptions[index].version = excp->version ();
3860 result[i].exceptions[index++].type =
3861 CORBA::TypeCode::_duplicate (CORBA::_tc_void);
3866 void
3867 ifr_adding_visitor::fill_get_exceptions (CORBA::ExceptionDefSeq &result,
3868 AST_Attribute *node)
3870 this->fill_exceptions (result,
3871 node->get_get_exceptions ());
3874 void
3875 ifr_adding_visitor::fill_set_exceptions (CORBA::ExceptionDefSeq &result,
3876 AST_Attribute *node)
3878 this->fill_exceptions (result,
3879 node->get_set_exceptions ());
3882 void
3883 ifr_adding_visitor::fill_exceptions (CORBA::ExceptionDefSeq &result,
3884 AST_Decl *node)
3886 switch (node->node_type ())
3888 case AST_Decl::NT_op:
3890 AST_Operation *op = dynamic_cast<AST_Operation*> (node);
3891 this->fill_exceptions (result,
3892 op->exceptions ());
3893 return;
3895 case AST_Decl::NT_factory:
3896 case AST_Decl::NT_finder:
3898 AST_Factory *f = dynamic_cast<AST_Factory*> (node);
3899 this->fill_exceptions (result,
3900 f->exceptions ());
3901 return;
3903 default:
3904 result.length (0);
3905 return;
3909 void
3910 ifr_adding_visitor::fill_exceptions (CORBA::ExceptionDefSeq &result,
3911 UTL_ExceptList *list)
3913 if (list == 0)
3915 result.length (0);
3916 return;
3919 result.length (static_cast<CORBA::ULong> (list->length ()));
3920 CORBA::ULong index = 0;
3921 AST_Decl *d = 0;
3922 CORBA::Contained_var holder;
3924 for (UTL_ExceptlistActiveIterator ei (list);
3925 !ei.is_done ();
3926 ei.next (), ++index)
3928 d = ei.item ();
3930 // Just to make sure. The call will return quickly if d has already
3931 // been visited. Can't use ir_current_ because ExceptionDef doesn't
3932 // inherit from IDLType.
3933 (void) d->ast_accept (this);
3935 holder = be_global->repository ()->lookup_id (d->repoID ());
3937 result[index] =
3938 CORBA::ExceptionDef::_narrow (holder.in ());
3942 void
3943 ifr_adding_visitor::fill_params (CORBA::ParDescriptionSeq &result,
3944 UTL_Scope *node)
3946 AST_Argument *arg = 0;
3947 CORBA::ULong n_args = static_cast<CORBA::ULong> (node->nmembers ());
3948 result.length (n_args);
3949 CORBA::ULong index = 0;
3950 CORBA::Contained_var holder;
3952 for (UTL_ScopeActiveIterator iter (node,
3953 UTL_Scope::IK_decls);
3954 ! iter.is_done ();
3955 iter.next (), ++index)
3957 arg = dynamic_cast<AST_Argument*> (iter.item ());
3958 result[index].name =
3959 CORBA::string_dup (arg->local_name ()->get_string ());
3960 result[index].type = CORBA::TypeCode::_duplicate (CORBA::_tc_void);
3962 // Get the arg type into ir_current_.
3963 (void) arg->ast_accept (this);
3965 result[index].type_def =
3966 CORBA::IDLType::_duplicate (this->ir_current_.in ());
3968 result[index].mode = CORBA::PARAM_IN;
3972 void
3973 ifr_adding_visitor::visit_all_factories (AST_Home *node,
3974 CORBA::ComponentIR::HomeDef_ptr h)
3976 CORBA::Contained_var contained;
3977 CORBA::ComponentIR::FactoryDef_var new_def;
3979 for (UTL_ScopeActiveIterator h_iter (node,
3980 UTL_Scope::IK_decls);
3981 !h_iter.is_done ();
3982 h_iter.next ())
3984 AST_Decl *d = h_iter.item ();
3985 AST_Decl::NodeType nt = d->node_type ();
3987 if (nt != AST_Decl::NT_factory)
3989 continue;
3992 AST_Factory *f = dynamic_cast<AST_Factory*> (d);
3994 CORBA::ParDescriptionSeq params;
3995 this->fill_params (params, f);
3997 CORBA::ExceptionDefSeq exceptions;
3998 this->fill_exceptions (exceptions, f);
4000 new_def = h->create_factory (f->repoID (),
4001 f->local_name ()->get_string (),
4002 f->version (),
4003 params,
4004 exceptions);
4008 void
4009 ifr_adding_visitor::visit_all_finders (AST_Home *node,
4010 CORBA::ComponentIR::HomeDef_ptr h)
4012 AST_Finder *f = 0;
4013 CORBA::Contained_var contained;
4014 CORBA::ComponentIR::FinderDef_var new_def;
4016 for (UTL_ScopeActiveIterator h_iter (node,
4017 UTL_Scope::IK_decls);
4018 !h_iter.is_done ();
4019 h_iter.next ())
4021 f = dynamic_cast<AST_Finder*> (h_iter.item ());
4023 if (f == 0)
4025 continue;
4028 CORBA::ParDescriptionSeq params;
4029 this->fill_params (params, f);
4031 CORBA::ExceptionDefSeq exceptions;
4032 this->fill_exceptions (exceptions, f);
4034 new_def = h->create_finder (f->repoID (),
4035 f->local_name ()->get_string (),
4036 f->version (),
4037 params,
4038 exceptions);
4042 void
4043 ifr_adding_visitor::expand_id (ACE_CString &str,
4044 const char *local_name)
4046 ssize_t pos = str.rfind (':');
4047 str = str.substr (0, pos) + '/' + local_name + str.substr (pos);