diff options
23 files changed, 1007 insertions, 888 deletions
diff --git a/TAO/TAO_IDL/ast/ast_constant.cpp b/TAO/TAO_IDL/ast/ast_constant.cpp index 33cbbacc94e..678130c42f7 100644 --- a/TAO/TAO_IDL/ast/ast_constant.cpp +++ b/TAO/TAO_IDL/ast/ast_constant.cpp @@ -130,7 +130,8 @@ exprtype_to_string (AST_Expression::ExprType et) // Default constructor. AST_Constant::AST_Constant (void) : pd_constant_value (0), - pd_et (AST_Expression::EV_none) + pd_et (AST_Expression::EV_none), + ifr_added_ (0) { } @@ -144,7 +145,8 @@ AST_Constant::AST_Constant (AST_Expression::ExprType t, n, p), pd_constant_value (idl_global->gen ()->create_expr (v, t)), - pd_et (t) + pd_et (t), + ifr_added_ (0) { } @@ -157,7 +159,8 @@ AST_Constant::AST_Constant (AST_Expression::ExprType t, n, p), pd_constant_value (idl_global->gen ()->create_expr (v, t)), - pd_et (t) + pd_et (t), + ifr_added_ (0) { } @@ -202,6 +205,18 @@ AST_Constant::et (void) return this->pd_et; } +idl_bool +AST_Constant::ifr_added (void) +{ + return this->ifr_added_; +} + +void +AST_Constant::ifr_added (idl_bool val) +{ + this->ifr_added_ = val; +} + // Narrowing methods. IMPL_NARROW_METHODS1(AST_Constant, AST_Decl) IMPL_NARROW_FROM_DECL(AST_Constant) diff --git a/TAO/TAO_IDL/ast/ast_decl.cpp b/TAO/TAO_IDL/ast/ast_decl.cpp index 060389221a3..9a7affdf9c6 100644 --- a/TAO/TAO_IDL/ast/ast_decl.cpp +++ b/TAO/TAO_IDL/ast/ast_decl.cpp @@ -545,6 +545,27 @@ AST_Decl::has_ancestor (AST_Decl *s) return ScopeAsDecl (pd_defined_in)->has_ancestor (s); } +idl_bool +AST_Decl::is_child (AST_Decl *s) +{ + if (this->defined_in ()) + { + AST_Decl *d = ScopeAsDecl (this->defined_in ()); + + if (d == 0) + { + return 0; + } + + if (ACE_OS::strcmp (d->full_name (), s->full_name ()) == 0) + { + return 1; + } + } + + return 0; // Not a child. +} + // Dump this AST_Decl to the ostream o. void AST_Decl::dump (ostream &o) diff --git a/TAO/TAO_IDL/ast/ast_type.cpp b/TAO/TAO_IDL/ast/ast_type.cpp index 424128be80f..59aeb18bee6 100644 --- a/TAO/TAO_IDL/ast/ast_type.cpp +++ b/TAO/TAO_IDL/ast/ast_type.cpp @@ -103,6 +103,30 @@ AST_Type::in_recursion (AST_Type *) return 0; } +idl_bool +AST_Type::ifr_added (void) +{ + return this->ifr_added_; +} + +void +AST_Type::ifr_added (idl_bool val) +{ + this->ifr_added_ = val; +} + +idl_bool +AST_Type::ifr_fwd_added (void) +{ + return this->ifr_fwd_added_; +} + +void +AST_Type::ifr_fwd_added (idl_bool val) +{ + this->ifr_fwd_added_ = val; +} + int AST_Type::ast_accept (ast_visitor *visitor) { diff --git a/TAO/TAO_IDL/be/be_decl.cpp b/TAO/TAO_IDL/be/be_decl.cpp index b127e49717d..f191d095623 100644 --- a/TAO/TAO_IDL/be/be_decl.cpp +++ b/TAO/TAO_IDL/be/be_decl.cpp @@ -762,29 +762,6 @@ be_decl::accept (be_visitor *visitor) } idl_bool -be_decl::is_child (be_decl *node) -{ - if (this->defined_in ()) - { - be_decl *bd = 0; - - bd = be_scope::narrow_from_scope (this->defined_in ())->decl (); - - if (bd == 0) - { - return 0; - } - - if (!ACE_OS::strcmp (bd->full_name (), node->full_name ())) - { - return 1; - } - } - - return 0; // Not a child. -} - -idl_bool be_decl::has_constructor (void) { return this->has_constructor_; diff --git a/TAO/TAO_IDL/be_include/be_decl.h b/TAO/TAO_IDL/be_include/be_decl.h index 62918398646..b32837fa52c 100644 --- a/TAO/TAO_IDL/be_include/be_decl.h +++ b/TAO/TAO_IDL/be_include/be_decl.h @@ -134,9 +134,6 @@ public: void cli_inline_cdr_op_gen (idl_bool); void cli_inline_cdr_decl_gen (idl_bool); - idl_bool is_child (be_decl *node); - // Am I a direct child of node? - // Narrowing DEF_NARROW_METHODS1 (be_decl, AST_Decl); DEF_NARROW_FROM_DECL (be_decl); diff --git a/TAO/TAO_IDL/include/ast_constant.h b/TAO/TAO_IDL/include/ast_constant.h index 00f25bb30e2..acbc0aa633e 100644 --- a/TAO/TAO_IDL/include/ast_constant.h +++ b/TAO/TAO_IDL/include/ast_constant.h @@ -104,6 +104,10 @@ public: AST_Expression::ExprType et (void); + // Accessors for the private member. + idl_bool ifr_added (void); + void ifr_added (idl_bool val); + // Narrowing DEF_NARROW_METHODS1(AST_Constant, AST_Decl); DEF_NARROW_FROM_DECL(AST_Constant); @@ -121,6 +125,9 @@ private: AST_Expression::ExprType pd_et; // Its expression type. + + idl_bool ifr_added_; + // Has this node been added to the IFR? }; #endif // _AST_CONSTANT_AST_CONSTANT_HH diff --git a/TAO/TAO_IDL/include/ast_decl.h b/TAO/TAO_IDL/include/ast_decl.h index 9d21bad13c8..69f2d49dde9 100644 --- a/TAO/TAO_IDL/include/ast_decl.h +++ b/TAO/TAO_IDL/include/ast_decl.h @@ -251,6 +251,9 @@ public: // Return TRUE if "this" has "s" as an ancestor. idl_bool has_ancestor (AST_Decl *s); + // Return TRUE if "this" is a child of "s". + idl_bool is_child (AST_Decl *s); + protected: // These are not private because they're used by // be_predefined_type' constructor. diff --git a/TAO/TAO_IDL/include/ast_type.h b/TAO/TAO_IDL/include/ast_type.h index 21a2aded5d8..f6d76d7087b 100644 --- a/TAO/TAO_IDL/include/ast_type.h +++ b/TAO/TAO_IDL/include/ast_type.h @@ -97,6 +97,14 @@ public: // Most types cannot be involved except structs and unions. // If the parameter is 0, we are trying to determine this for ourselves. + // Accessors/mutators for the private members. + + idl_bool ifr_added (void); + void ifr_added (idl_bool val); + + idl_bool ifr_fwd_added (void); + void ifr_fwd_added (idl_bool val); + // Narrowing. DEF_NARROW_METHODS1(AST_Type, AST_Decl); DEF_NARROW_FROM_DECL(AST_Type); @@ -104,6 +112,7 @@ public: // Visiting. virtual int ast_accept (ast_visitor *visitor); +protected: // Has the full definition been added to the Interface Repository? // Used for types which can have members and can be forward declared. idl_bool ifr_added_; diff --git a/TAO/orbsvcs/IFR_Service/InterfaceDef_i.cpp b/TAO/orbsvcs/IFR_Service/InterfaceDef_i.cpp index 346c0932bdb..0cb3193b5ad 100644 --- a/TAO/orbsvcs/IFR_Service/InterfaceDef_i.cpp +++ b/TAO/orbsvcs/IFR_Service/InterfaceDef_i.cpp @@ -1155,7 +1155,7 @@ TAO_InterfaceDef_i::create_attr_ops (const char *id, params.length (1); params[0].name = name; - params[0].type = CORBA::TypeCode::_duplicate (CORBA::_tc_null); + params[0].type = CORBA::TypeCode::_duplicate (CORBA::_tc_void); params[0].type_def = CORBA::IDLType::_duplicate (type); params[0].mode = CORBA::PARAM_IN; diff --git a/TAO/orbsvcs/IFR_Service/be_global.cpp b/TAO/orbsvcs/IFR_Service/be_global.cpp index 2a5bfb09810..a4d6a156875 100644 --- a/TAO/orbsvcs/IFR_Service/be_global.cpp +++ b/TAO/orbsvcs/IFR_Service/be_global.cpp @@ -25,7 +25,9 @@ TAO_IFR_BE_Export BE_GlobalData *be_global = 0; BE_GlobalData::BE_GlobalData (void) : removing_ (0), - enable_locking_ (0) + holding_scope_name_ (CORBA::string_dup ("TAO_IFR_holding_scope_module")), + enable_locking_ (0), + do_included_files_ (1) { } @@ -69,6 +71,24 @@ BE_GlobalData::repository (CORBA_Repository_ptr repo) this->repository_ = repo; } +CORBA_ModuleDef_ptr +BE_GlobalData::holding_scope (void) const +{ + return this->holding_scope_.in (); +} + +void +BE_GlobalData::holding_scope (CORBA_ModuleDef_ptr scope) +{ + this->holding_scope_ = scope; +} + +const char * +BE_GlobalData::holding_scope_name (void) const +{ + return this->holding_scope_name_.in (); +} + ACE_Unbounded_Stack<CORBA_Container_ptr> & BE_GlobalData::ifr_scopes (void) { @@ -76,7 +96,7 @@ BE_GlobalData::ifr_scopes (void) } const char * -BE_GlobalData::filename (void) +BE_GlobalData::filename (void) const { return this->filename_; } @@ -88,7 +108,7 @@ BE_GlobalData::filename (char *fname) } idl_bool -BE_GlobalData::enable_locking (void) +BE_GlobalData::enable_locking (void) const { return this->enable_locking_; } @@ -99,6 +119,18 @@ BE_GlobalData::enable_locking (idl_bool value) this->enable_locking_ = value; } +idl_bool +BE_GlobalData::do_included_files (void) const +{ + return this->do_included_files_; +} + +void +BE_GlobalData::do_included_files (idl_bool val) +{ + this->do_included_files_ = val; +} + #if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) template class ACE_Unbounded_Stack<CORBA_Container_ptr>; diff --git a/TAO/orbsvcs/IFR_Service/be_global.h b/TAO/orbsvcs/IFR_Service/be_global.h index 8f2de45a5aa..f958cc56490 100644 --- a/TAO/orbsvcs/IFR_Service/be_global.h +++ b/TAO/orbsvcs/IFR_Service/be_global.h @@ -61,16 +61,26 @@ public: void repository (CORBA_Repository_ptr repo); + CORBA_ModuleDef_ptr holding_scope (void) const; + + void holding_scope (CORBA_ModuleDef_ptr scope); + + const char *holding_scope_name (void) const; + ACE_Unbounded_Stack<CORBA_Container_ptr> &ifr_scopes (void); - const char *filename (void); + const char *filename (void) const; void filename (char *fname); - idl_bool enable_locking (void); + idl_bool enable_locking (void) const; void enable_locking (idl_bool value); + idl_bool do_included_files (void) const; + + void do_included_files (idl_bool val); + private: idl_bool removing_; // Are we removing IR objects from the repository? @@ -81,6 +91,13 @@ private: CORBA_Repository_var repository_; // Reference to the interface repository. + CORBA_ModuleDef_var holding_scope_; + // Used to hold struct/union/exception member defns until + // they are moved into their permanent scope. + + CORBA::String_var holding_scope_name_; + // Must be something unlikely to clash. + ACE_Unbounded_Stack<CORBA_Container_ptr> ifr_scopes_; // IR object scope stack. @@ -89,6 +106,9 @@ private: idl_bool enable_locking_; // Option to lock at the IDL file level. + + idl_bool do_included_files_; + // Option to process included IDL files. }; #endif /* TAO_IFR_BE_GLOBAL_H */ diff --git a/TAO/orbsvcs/IFR_Service/be_produce.cpp b/TAO/orbsvcs/IFR_Service/be_produce.cpp index 8b54353f175..299d407c046 100644 --- a/TAO/orbsvcs/IFR_Service/be_produce.cpp +++ b/TAO/orbsvcs/IFR_Service/be_produce.cpp @@ -91,6 +91,33 @@ BE_cleanup (void) idl_global->destroy (); delete idl_global; idl_global = 0; + + // Remove the holding scope entry from the repository. + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY + { + CORBA_Contained_var result = + be_global->repository ()->lookup_id (be_global->holding_scope_name (), + ACE_TRY_ENV); + ACE_TRY_CHECK; + + if (!CORBA::is_nil (result.in ())) + { + CORBA_ModuleDef_var scope = + CORBA_ModuleDef::_narrow (result.in (), + ACE_TRY_ENV); + ACE_TRY_CHECK; + + scope->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + } + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION (ACE_ANY_EXCEPTION, + ACE_TEXT ("BE_cleanup")); + } + ACE_ENDTRY; } // Abort this run of the BE. @@ -165,26 +192,61 @@ BE_ifr_init (int &ac, return 0; } -// Do the work of this BE. This is the starting point for code generation. -TAO_IFR_BE_Export void -BE_produce (void) +void +BE_create_holding_scope (CORBA::Environment &ACE_TRY_ENV) { - // Get the root node. - AST_Decl *d = idl_global->root (); - AST_Root *root = AST_Root::narrow_from_decl (d); + CORBA_ModuleDef_ptr scope = CORBA_ModuleDef::_nil (); - if (root == 0) - { - ACE_ERROR ((LM_ERROR, - ACE_TEXT ("(%N:%l) BE_produce - ") - ACE_TEXT ("No Root\n"))); + // If we are multi-threaded, it may already be created. + CORBA_Contained_var result = + be_global->repository ()->lookup_id (be_global->holding_scope_name (), + ACE_TRY_ENV); + ACE_CHECK; - BE_abort (); + if (CORBA::is_nil (result.in ())) + { + scope = + be_global->repository ()->create_module ( + be_global->holding_scope_name (), + be_global->holding_scope_name (), + "1.0", + ACE_TRY_ENV + ); + ACE_CHECK; + } + else + { + scope = CORBA_ModuleDef::_narrow (result.in (), + ACE_TRY_ENV); + ACE_CHECK; } + be_global->holding_scope (scope); +} + +// Do the work of this BE. This is the starting point for code generation. +TAO_IFR_BE_Export void +BE_produce (void) +{ ACE_DECLARE_NEW_CORBA_ENV; ACE_TRY { + BE_create_holding_scope (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // Get the root node. + AST_Decl *d = idl_global->root (); + AST_Root *root = AST_Root::narrow_from_decl (d); + + if (root == 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%N:%l) BE_produce - ") + ACE_TEXT ("No Root\n"))); + + BE_abort (); + } + if (be_global->removing ()) { ifr_removing_visitor visitor; @@ -204,7 +266,7 @@ BE_produce (void) } else { - ifr_adding_visitor visitor; + ifr_adding_visitor visitor (d); TAO_IFR_VISITOR_WRITE_GUARD; diff --git a/TAO/orbsvcs/IFR_Service/drv_args_ifr.cpp b/TAO/orbsvcs/IFR_Service/drv_args_ifr.cpp index 509af4e9751..6e93aa42f2d 100644 --- a/TAO/orbsvcs/IFR_Service/drv_args_ifr.cpp +++ b/TAO/orbsvcs/IFR_Service/drv_args_ifr.cpp @@ -65,6 +65,10 @@ DRV_usage (void) )); ACE_DEBUG (( LM_DEBUG, + ACE_TEXT (" -Si\t\t\tSuppress processing of included IDL files\n") + )); + ACE_DEBUG (( + LM_DEBUG, ACE_TEXT (" -t\t\t\tTemporary directory to be used") ACE_TEXT (" by the IDL compiler.\n") )); @@ -182,6 +186,24 @@ DRV_parse_args (int ac, char *av[]) idl_global->set_compile_flags (idl_global->compile_flags () | IDL_CF_NOWARNINGS); break; + case 'S': + // Suppress ... + if (av[i][2] == 'i') + { + // ... processing of included IDL files. + be_global->do_included_files (0); + } + else + { + ACE_ERROR (( + LM_ERROR, + ACE_TEXT ("IDL: I don't understand the '%s' option\n"), + av[i] + )); + + ACE_OS::exit (99); + } + break; case 'Y': if (av[i][2] == '\0') { diff --git a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor.cpp b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor.cpp index d4abce81d35..4f3a849950e 100644 --- a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor.cpp +++ b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor.cpp @@ -9,7 +9,8 @@ ACE_RCSID(IFR_Service, ifr_adding_visitor, "$Id$") -ifr_adding_visitor::ifr_adding_visitor (void) +ifr_adding_visitor::ifr_adding_visitor (AST_Decl *scope) + : scope_ (scope) { } @@ -99,6 +100,11 @@ ifr_adding_visitor::visit_predefined_type (AST_PredefinedType *node) int ifr_adding_visitor::visit_module (AST_Module *node) { + if (node->imported () && !be_global->do_included_files ()) + { + return 0; + } + CORBA_Container_var new_def; ACE_DECLARE_NEW_CORBA_ENV; @@ -139,28 +145,27 @@ ifr_adding_visitor::visit_module (AST_Module *node) } else { - // Reopened module. - new_def = CORBA_ModuleDef::_narrow (prev_def.in (), - ACE_TRY_ENV); + CORBA::DefinitionKind kind = prev_def->def_kind (ACE_TRY_ENV); ACE_TRY_CHECK; - // Nothing prevents this modules's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before we make a - // call on new_def. - if (CORBA::is_nil (new_def.in ())) + // If the line below is true, we are clobbering a previous + // entry from another IDL file. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (kind != CORBA::dk_Module) { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_module -") - ACE_TEXT (" module %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // This call will take the brach where prev_def.in() is 0. + return this->visit_module (node); + } + else + { + new_def = + CORBA_Container::_narrow (prev_def.in (), + ACE_TRY_ENV); + ACE_TRY_CHECK; } } @@ -214,6 +219,11 @@ ifr_adding_visitor::visit_module (AST_Module *node) int ifr_adding_visitor::visit_interface (AST_Interface *node) { + if (node->imported () && !be_global->do_included_files ()) + { + return 0; + } + // If the node is really a valuetype, go there instead. if (node->is_valuetype ()) { @@ -232,138 +242,11 @@ ifr_adding_visitor::visit_interface (AST_Interface *node) // If not, create a new entry. if (CORBA::is_nil (prev_def.in ())) { - CORBA::ULong n_parents = ACE_static_cast (CORBA::ULong, - node->n_inherits ()); - - CORBA_InterfaceDefSeq bases (n_parents); - bases.length (n_parents); - CORBA_Contained_var result; - - AST_Interface **parents = node->inherits (); - - // Construct a list of the parents. - for (CORBA::ULong i = 0; i < n_parents; ++i) - { - result = - be_global->repository ()->lookup_id (parents[i]->repoID (), - ACE_TRY_ENV); - ACE_TRY_CHECK - - bases[i] = CORBA_InterfaceDef::_narrow (result.in (), - ACE_TRY_ENV); - ACE_TRY_CHECK; - - if (CORBA::is_nil (bases[i].in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::") - ACE_TEXT ("visit_interface -") - ACE_TEXT (" CORBA_InterfaceDef::_narrow failed\n") - ), - -1 - ); - } - } - - CORBA_Container_ptr current_scope = CORBA_Container::_nil (); - - if (be_global->ifr_scopes ().top (current_scope) == 0) - { - CORBA_InterfaceDef_var new_def; - - if (node->is_local ()) - { - new_def = - current_scope->create_local_interface ( - node->repoID (), - node->local_name ()->get_string (), - this->gen_version (node), - bases, - ACE_TRY_ENV - ); - } - else - { - new_def = - current_scope->create_interface ( - node->repoID (), - node->local_name ()->get_string (), - this->gen_version (node), - bases, - ACE_TRY_ENV - ); - } - - ACE_TRY_CHECK; - - node->ifr_added_ = 1; - - // Push the new IR object onto the scope stack. - CORBA_Container_var new_scope = - CORBA_Container::_narrow (new_def.in (), - ACE_TRY_ENV); - ACE_TRY_CHECK; - - if (be_global->ifr_scopes ().push (new_scope.in ()) != 0) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::") - ACE_TEXT ("visit_interface -") - ACE_TEXT (" scope push failed\n") - ), - -1 - ); - } - - // Visit the members, if any. - if (this->visit_scope (node) == -1) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::") - ACE_TEXT ("visit_interface -") - ACE_TEXT (" visit_scope failed\n") - ), - -1 - ); - } - - // This spot in the AST doesn't necessarily have to be the - // interface definition - it could be any reference to it. - // The front end will already have fully defined it, so all - // the info in available anywhere. So it's a good idea to - // update the current IR object holder now. This will - // consume the objref pointer. - this->ir_current_ = - CORBA_IDLType::_duplicate (new_def.in ()); - - CORBA_Container_ptr used_scope = CORBA_Container::_nil (); + int status = this->create_interface_def (node, + ACE_TRY_ENV); + ACE_TRY_CHECK; - // Pop the new IR object back off the scope stack. - if (be_global->ifr_scopes ().pop (used_scope) != 0) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::") - ACE_TEXT ("visit_interface -") - ACE_TEXT (" scope pop failed\n") - ), - -1 - ); - } - } - else - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_interface -") - ACE_TEXT (" scope stack is empty\n") - ), - -1 - ); - } + return status; } else { @@ -372,40 +255,27 @@ ifr_adding_visitor::visit_interface (AST_Interface *node) // now. If it is not yet defined or the full definition has already // been added to the repository, we just update the current IR object // holder. - if (node->is_defined () && node->ifr_added_ == 0) + if (node->is_defined () && node->ifr_added () == 0) { - CORBA_InterfaceDef_var extant_def = - CORBA_InterfaceDef::_narrow (prev_def.in (), - ACE_TRY_ENV); - ACE_TRY_CHECK; - - // Nothing prevents this interface's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before we make a - // call on extant_def. - if (CORBA::is_nil (extant_def.in ())) + // If we are here and the line below is true, then either + // 1. We are defining an undefined forward declared interface + // from a previously processed IDL file, or + // 2. We are clobbering a previous definition, either of an + // interface or of some other type. + // If prev_def would narrow successfully to an InterfaceDef, we + // have NO WAY of knowing if we are defining or clobbering. So + // we take the path of other ORB vendors and destroy the + // previous IFR entry, then create a new one. + if (node->ifr_fwd_added () == 0) { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_interface -") - ACE_TEXT (" interface %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } - else if (node->ifr_fwd_added_ == 0) - { - // No way to tell if this is just the definition of a forward - // declaration from another file, or an error. This warning - // will let the user decide, and roll back the processing of - // this IDL file if necessary. - this->redef_warning (node); + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + int status = this->create_interface_def (node, + ACE_TRY_ENV) + ACE_TRY_CHECK; - return -1; + return status; } CORBA::ULong n_parents = ACE_static_cast (CORBA::ULong, @@ -457,19 +327,19 @@ ifr_adding_visitor::visit_interface (AST_Interface *node) } } + CORBA_InterfaceDef_var extant_def = + CORBA_InterfaceDef::_narrow (prev_def. in (), + ACE_TRY_ENV); + ACE_TRY_CHECK; + extant_def->base_interfaces (bases, ACE_TRY_ENV); ACE_TRY_CHECK - node->ifr_added_ = 1; - - CORBA_Container_var new_scope = - CORBA_Container::_narrow (extant_def.in (), - ACE_TRY_ENV); - ACE_TRY_CHECK; + node->ifr_added (1); // Push the new IR object onto the scope stack. - if (be_global->ifr_scopes ().push (new_scope.in ()) != 0) + if (be_global->ifr_scopes ().push (extant_def.in ()) != 0) { ACE_ERROR_RETURN (( LM_ERROR, @@ -519,22 +389,15 @@ ifr_adding_visitor::visit_interface (AST_Interface *node) } else { - this->ir_current_ = - CORBA_InterfaceDef::_narrow (prev_def.in (), - ACE_TRY_ENV); + // @@ (JP) I think we're ok here without a check: + // not defined/not added - visit_interface_fwd will have + // detected a clobber. + // not defined/added - not possible. + // defined/not added - takes the other branch. + // defined/added - we're ok. + this->ir_current_ = CORBA_IDLType::_narrow (prev_def.in (), + ACE_TRY_ENV); ACE_TRY_CHECK; - - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::") - ACE_TEXT ("visit_interface -") - ACE_TEXT (" CORBA_InterfaceDef::_narrow failed\n") - ), - -1 - ); - } } } } @@ -553,6 +416,11 @@ ifr_adding_visitor::visit_interface (AST_Interface *node) int ifr_adding_visitor::visit_interface_fwd (AST_InterfaceFwd *node) { + if (node->imported () && !be_global->do_included_files ()) + { + return 0; + } + AST_Interface *i = node->full_definition (); ACE_DECLARE_NEW_CORBA_ENV; @@ -566,6 +434,8 @@ ifr_adding_visitor::visit_interface_fwd (AST_InterfaceFwd *node) if (CORBA::is_nil (prev_def.in ())) { + // If our full definition is found in this IDL file, we go + // ahead and create the full entry now. // The forward declared interface is not defined anywhere // in this IDL file, so we just create an empty entry to // be populated by some other IDL file. @@ -573,7 +443,7 @@ ifr_adding_visitor::visit_interface_fwd (AST_InterfaceFwd *node) bases.length (0); CORBA_Container_ptr current_scope = CORBA_Container::_nil (); - + if (be_global->ifr_scopes ().top (current_scope) == 0) { if (i->is_local ()) @@ -612,38 +482,33 @@ ifr_adding_visitor::visit_interface_fwd (AST_InterfaceFwd *node) -1 ); } + + node->ifr_added (1); } else { + // If the line below is true, we are clobbering a previous + // entry from another IDL file. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // This call will take the other branch of + // "if (CORBA::is_nil (prev_def.in ()))" + return this->visit_interface_fwd (node); + } + // There is already an entry in the repository, so just update // the current IR object holder. - this->ir_current_ = - CORBA_InterfaceDef::_narrow (prev_def.in (), - ACE_TRY_ENV); + this->ir_current_ = CORBA_IDLType::_narrow (prev_def.in (), + ACE_TRY_ENV); ACE_TRY_CHECK; - - // Nothing prevents this interface's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before we make a - // call on ir_current_. - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::") - ACE_TEXT ("visit_interface_fwd -") - ACE_TEXT (" interface %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } } - i->ifr_fwd_added_ = 1; + i->ifr_fwd_added (1); } ACE_CATCHANY { @@ -672,6 +537,11 @@ ifr_adding_visitor::visit_valuetype_fwd (AST_InterfaceFwd *) int ifr_adding_visitor::visit_structure (AST_Structure *node) { + if (node->imported () && !be_global->do_included_files ()) + { + return 0; + } + ACE_DECLARE_NEW_CORBA_ENV; ACE_TRY { @@ -682,7 +552,8 @@ ifr_adding_visitor::visit_structure (AST_Structure *node) if (CORBA::is_nil (prev_def.in ())) { - ifr_adding_visitor_structure visitor (0); + ifr_adding_visitor_structure visitor (node, + 0); int retval = visitor.visit_structure (node); @@ -696,29 +567,22 @@ ifr_adding_visitor::visit_structure (AST_Structure *node) } else { + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + return this->visit_structure (node); + } + this->ir_current_ = CORBA_IDLType::_narrow (prev_def.in (), ACE_TRY_ENV); ACE_TRY_CHECK; - - // Nothing prevents this struct's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before we make a - // call on ir_current_. - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_structure -") - ACE_TEXT (" struct %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } } } ACE_CATCHANY @@ -736,7 +600,12 @@ ifr_adding_visitor::visit_structure (AST_Structure *node) int ifr_adding_visitor::visit_exception (AST_Exception *node) { - ifr_adding_visitor_exception visitor; + if (node->imported () && !be_global->do_included_files ()) + { + return 0; + } + + ifr_adding_visitor_exception visitor (node); // No point in updating ir_current_ here because // ExceptionDef is not an IDLType. @@ -747,6 +616,11 @@ ifr_adding_visitor::visit_exception (AST_Exception *node) int ifr_adding_visitor::visit_enum (AST_Enum *node) { + if (node->imported () && !be_global->do_included_files ()) + { + return 0; + } + ACE_DECLARE_NEW_CORBA_ENV; ACE_TRY { @@ -803,34 +677,29 @@ ifr_adding_visitor::visit_enum (AST_Enum *node) -1 ); } + + node->ifr_added (1); } else { + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + return this->visit_enum (node); + } + // There is already an entry in the repository, so just update // the current IR object holder. this->ir_current_ = CORBA_EnumDef::_narrow (prev_def.in (), ACE_TRY_ENV); ACE_TRY_CHECK; - - // Nothing prevents this enum's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before we make a - // call on ir_current_. - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_enum -") - ACE_TEXT (" enum %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } } } ACE_CATCHANY @@ -848,7 +717,7 @@ ifr_adding_visitor::visit_enum (AST_Enum *node) int ifr_adding_visitor::visit_operation (AST_Operation *node) { - ifr_adding_visitor_operation visitor; + ifr_adding_visitor_operation visitor (node); return visitor.visit_operation (node); } @@ -891,89 +760,43 @@ ifr_adding_visitor::visit_attribute (AST_Attribute *node) ACE_DECLARE_NEW_CORBA_ENV; ACE_TRY { - CORBA_Contained_var prev_def = - be_global->repository ()->lookup_id (node->repoID (), - ACE_TRY_ENV); - ACE_TRY_CHECK; - - CORBA_AttributeDef_var new_def; - - if (CORBA::is_nil (prev_def.in ())) - { - CORBA::AttributeMode mode = - node->readonly () ? CORBA::ATTR_READONLY : CORBA::ATTR_NORMAL; + AST_Type *type = node->field_type (); - AST_Type *type = node->field_type (); - - // If this type already has a repository entry, the call - // will just update the current IR object holder. Otherwise, - // it will create the entry. - if (type->ast_accept (this) == -1) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::") - ACE_TEXT ("visit_attribute - ") - ACE_TEXT ("failed to accept visitor\n") - ), - -1 - ); - } + // Updates ir_current_. + this->get_referenced_type (type, + ACE_TRY_ENV); + ACE_TRY_CHECK; - CORBA_Container_ptr current_scope = CORBA_Container::_nil (); + CORBA::AttributeMode mode = + node->readonly () ? CORBA::ATTR_READONLY : CORBA::ATTR_NORMAL; - if (be_global->ifr_scopes ().top (current_scope) == 0) - { - CORBA_InterfaceDef_var iface = - CORBA_InterfaceDef::_narrow (current_scope, - ACE_TRY_ENV); - ACE_TRY_CHECK; + CORBA_Container_ptr current_scope = CORBA_Container::_nil (); - new_def = - iface->create_attribute (node->repoID (), - node->local_name ()->get_string (), - this->gen_version (node), - this->ir_current_.in (), - mode, - ACE_TRY_ENV); - ACE_TRY_CHECK; - } - else - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_attribute -") - ACE_TEXT (" scope stack is empty\n") - ), - -1 - ); - } - } - else + if (be_global->ifr_scopes ().top (current_scope) == 0) { - new_def = - CORBA_AttributeDef::_narrow (prev_def.in (), + CORBA_InterfaceDef_var iface = + CORBA_InterfaceDef::_narrow (current_scope, ACE_TRY_ENV); ACE_TRY_CHECK; - // Nothing prevents this attribute's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before we make a - // call on new_def. - if (CORBA::is_nil (new_def.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_attribute -") - ACE_TEXT (" attribute %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } + CORBA_AttributeDef_var new_def = + iface->create_attribute (node->repoID (), + node->local_name ()->get_string (), + this->gen_version (node), + this->ir_current_.in (), + mode, + ACE_TRY_ENV); + ACE_TRY_CHECK; + } + else + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_attribute -") + ACE_TEXT (" scope stack is empty\n") + ), + -1 + ); } } ACE_CATCHANY @@ -991,6 +814,11 @@ ifr_adding_visitor::visit_attribute (AST_Attribute *node) int ifr_adding_visitor::visit_union (AST_Union *node) { + if (node->imported () && !be_global->do_included_files ()) + { + return 0; + } + ACE_DECLARE_NEW_CORBA_ENV; ACE_TRY { @@ -1001,7 +829,8 @@ ifr_adding_visitor::visit_union (AST_Union *node) if (CORBA::is_nil (prev_def.in ())) { - ifr_adding_visitor_union visitor (0); + ifr_adding_visitor_union visitor (node, + 0); int retval = visitor.visit_union (node); @@ -1015,29 +844,22 @@ ifr_adding_visitor::visit_union (AST_Union *node) } else { + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + return this->visit_union (node); + } + this->ir_current_ = CORBA_UnionDef::_narrow (prev_def.in (), ACE_TRY_ENV); ACE_TRY_CHECK; - - // Nothing prevents this union's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before we make a - // call on ir_current_. - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_union -") - ACE_TEXT (" union %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } } } ACE_CATCHANY @@ -1053,40 +875,13 @@ ifr_adding_visitor::visit_union (AST_Union *node) } int -ifr_adding_visitor::visit_union_branch (AST_UnionBranch *node) +ifr_adding_visitor::visit_constant (AST_Constant *node) { - AST_Type *ft = AST_Type::narrow_from_decl (node->field_type ()); - - if (ft == 0) + if (node->imported () && !be_global->do_included_files ()) { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::") - ACE_TEXT ("visit_union_branch - ") - ACE_TEXT ("Bad field type\n") - ), - -1 - ); + return 0; } - if (ft->ast_accept (this) == -1) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::") - ACE_TEXT ("visit_union_branch - ") - ACE_TEXT ("failed to accept visitor\n") - ), - -1 - ); - } - - return 0; -} - -int -ifr_adding_visitor::visit_constant (AST_Constant *node) -{ const char *id = node->repoID (); ACE_DECLARE_NEW_CORBA_ENV; @@ -1103,28 +898,22 @@ ifr_adding_visitor::visit_constant (AST_Constant *node) // code from this IDL file. So we check here before we make a // call on ir_current_. if (!CORBA::is_nil (prev_def.in ())) - { - CORBA_ConstantDef_var const_def = - CORBA_ConstantDef::_narrow (prev_def.in (), - ACE_TRY_ENV); - ACE_TRY_CHECK; - - if (CORBA::is_nil (const_def.in ())) + { + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_constant -") - ACE_TEXT (" constant %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + } + else + { + // The node is referenced in an array size, string bound + // or sequence bound - no action needed in the IFR. + return 0; } - - // If everything's ok, just return. - return 0; } AST_Expression::AST_ExprValue *ev = node->constant_value ()->ev (); @@ -1286,6 +1075,11 @@ ifr_adding_visitor::visit_string (AST_String *node) int ifr_adding_visitor::visit_typedef (AST_Typedef *node) { + if (node->imported () && !be_global->do_included_files ()) + { + return 0; + } + ACE_DECLARE_NEW_CORBA_ENV; ACE_TRY { @@ -1326,34 +1120,28 @@ ifr_adding_visitor::visit_typedef (AST_Typedef *node) -1 ); } + + node->ifr_added (1); } else { - // There is already an entry in the repository, so just update - // the current IR object holder. + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // This call will take the other branch. + return this->visit_typedef (node); + } + this->ir_current_ = CORBA_TypedefDef::_narrow (prev_def.in (), ACE_TRY_ENV); ACE_TRY_CHECK; - - // Nothing prevents this typedef's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before we make a - // call on ir_current_. - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_typedef -") - ACE_TEXT (" typedef %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } } } ACE_CATCHANY @@ -1429,6 +1217,11 @@ ifr_adding_visitor::visit_root (AST_Root *node) int ifr_adding_visitor::visit_native (AST_Native *node) { + if (node->imported () && !be_global->do_included_files ()) + { + return 0; + } + ACE_DECLARE_NEW_CORBA_ENV; ACE_TRY { @@ -1462,33 +1255,28 @@ ifr_adding_visitor::visit_native (AST_Native *node) -1 ); } + + node->ifr_added (1); } else { + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // This call will take the other branch. + return this->visit_native (node); + } + this->ir_current_ = CORBA_NativeDef::_narrow (prev_def.in (), ACE_TRY_ENV); ACE_TRY_CHECK; - - // Nothing prevents this native type's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before we make a - // call on ir_current_. - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_native -") - ACE_TEXT (" native type %s, in IDL file %s, ") - ACE_TEXT ("already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } } } ACE_CATCHANY @@ -1724,17 +1512,200 @@ ifr_adding_visitor::element_type (AST_Type *base_type, } } -void -ifr_adding_visitor::redef_warning (AST_Decl *node) +int +ifr_adding_visitor::create_interface_def (AST_Interface *node, + CORBA::Environment &ACE_TRY_ENV) { - ACE_DEBUG ((LM_DEBUG, - ACE_TEXT ("Warning: there is already an entry in the") - ACE_TEXT (" repository with this type and name %s. If this") - ACE_TEXT (" is because of a forward declaration in another") - ACE_TEXT (" IDL file, ignore this warning. Otherwise,remove") - ACE_TEXT (" this IDL file's contents from the repository") - ACE_TEXT (" with 'tao_ifr -r %s'\n"), - node->full_name (), - be_global->filename ())); + CORBA::ULong n_parents = ACE_static_cast (CORBA::ULong, + node->n_inherits ()); + + CORBA_InterfaceDefSeq bases (n_parents); + bases.length (n_parents); + CORBA_Contained_var result; + + AST_Interface **parents = node->inherits (); + + // Construct a list of the parents. + for (CORBA::ULong i = 0; i < n_parents; ++i) + { + // If we got to visit_interface() from a forward declared interface, + // this node may not yet be in the repository. If it is, this + // call will merely update ir_current_. + if (this->visit_interface (parents[i]) == -1) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("(%N:%l) ifr_adding_visitor::") + ACE_TEXT ("visit_interface - call for parent node failed\n") + ), + -1 + ); + } + + result = + be_global->repository ()->lookup_id (parents[i]->repoID (), + ACE_TRY_ENV); + ACE_CHECK_RETURN (-1); + + bases[i] = CORBA_InterfaceDef::_narrow (result.in (), + ACE_TRY_ENV); + ACE_CHECK_RETURN (-1); + + if (CORBA::is_nil (bases[i].in ())) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("(%N:%l) ifr_adding_visitor::") + ACE_TEXT ("visit_interface -") + ACE_TEXT (" CORBA_InterfaceDef::_narrow failed\n") + ), + -1 + ); + } + } + + CORBA_Container_ptr current_scope = CORBA_Container::_nil (); + + if (be_global->ifr_scopes ().top (current_scope) == 0) + { + CORBA_InterfaceDef_var new_def; + + if (node->is_local ()) + { + new_def = + current_scope->create_local_interface ( + node->repoID (), + node->local_name ()->get_string (), + this->gen_version (node), + bases, + ACE_TRY_ENV + ); + } + else + { + new_def = + current_scope->create_interface ( + node->repoID (), + node->local_name ()->get_string (), + this->gen_version (node), + bases, + ACE_TRY_ENV + ); + } + + ACE_CHECK_RETURN (-1); + + node->ifr_added (1); + + // Push the new IR object onto the scope stack. + CORBA_Container_var new_scope = + CORBA_Container::_narrow (new_def.in (), + ACE_TRY_ENV); + ACE_CHECK_RETURN (-1); + + if (be_global->ifr_scopes ().push (new_scope.in ()) != 0) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("(%N:%l) ifr_adding_visitor::") + ACE_TEXT ("visit_interface -") + ACE_TEXT (" scope push failed\n") + ), + -1 + ); + } + + // Visit the members, if any. + if (this->visit_scope (node) == -1) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("(%N:%l) ifr_adding_visitor::") + ACE_TEXT ("visit_interface -") + ACE_TEXT (" visit_scope failed\n") + ), + -1 + ); + } + + // This spot in the AST doesn't necessarily have to be the + // interface definition - it could be any reference to it. + // The front end will already have fully defined it, so all + // the info in available anywhere. So it's a good idea to + // update the current IR object holder now. This will + // consume the objref pointer. + this->ir_current_ = + CORBA_IDLType::_duplicate (new_def.in ()); + + CORBA_Container_ptr used_scope = CORBA_Container::_nil (); + + // Pop the new IR object back off the scope stack. + if (be_global->ifr_scopes ().pop (used_scope) != 0) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("(%N:%l) ifr_adding_visitor::") + ACE_TEXT ("visit_interface -") + ACE_TEXT (" scope pop failed\n") + ), + -1 + ); + } + } + else + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("(%N:%l) ifr_adding_visitor::visit_interface -") + ACE_TEXT (" scope stack is empty\n") + ), + -1 + ); + } + + return 0; } +void +ifr_adding_visitor::get_referenced_type (AST_Type *node, + CORBA::Environment &ACE_TRY_ENV) +{ + switch (node->node_type ()) + { + // For anonymous types, a new IR object is be created each + // time, so we just visit the node, which get the object and + // updates ir_current_. + case AST_Decl::NT_pre_defined: + case AST_Decl::NT_string: + case AST_Decl::NT_wstring: + case AST_Decl::NT_array: + case AST_Decl::NT_sequence: + if (node->ast_accept (this) == -1) + { + ACE_ERROR (( + LM_ERROR, + ACE_TEXT ("(%N:%l) ifr_adding_visitor::") + ACE_TEXT ("get_scope_member -") + ACE_TEXT (" failed to accept visitor\n") + )); + } + + ACE_UNUSED_ARG (ACE_TRY_ENV); + break; + // For names types, we can just look up the entry and update + // ir_current_. + default: + { + CORBA_Contained_var prev_def = + be_global->repository ()->lookup_id (node->repoID (), + ACE_TRY_ENV); + ACE_CHECK; + + this->ir_current_ = + CORBA_IDLType::_narrow (prev_def.in (), + ACE_TRY_ENV); + ACE_CHECK; + break; + } + } +} diff --git a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor.h b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor.h index af8a3cdba41..6fdc248558b 100644 --- a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor.h +++ b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor.h @@ -38,7 +38,7 @@ class ifr_adding_visitor : public ifr_visitor // to the Interface Repository. // public: - ifr_adding_visitor (void); + ifr_adding_visitor (AST_Decl *scope); // Constructor. virtual ~ifr_adding_visitor (void); @@ -86,9 +86,6 @@ public: virtual int visit_union (AST_Union *node); // Visit union. - virtual int visit_union_branch (AST_UnionBranch *node); - // Visit union branch. - virtual int visit_constant (AST_Constant *node); // Visit a constant. @@ -127,17 +124,23 @@ protected: // Creates or looks up the element type of an array or sequence, // and stores the result in ir_current_. - void redef_warning (AST_Decl *node); - // If a type that can be forward declared is seen in an IDL file, - // and there is already a repository entry for a declaration of - // the same type, it may be an error. This warning lets the user - // decide. + int create_interface_def (AST_Interface *node, + CORBA::Environment &ACE_TRY_ENV); + // Common code factored out of visit_interface(). + + void get_referenced_type (AST_Type *node, + CORBA::Environment &ACE_TRY_ENV); + // Utility method to update ir_current_ for struct members, union + // members, operation parameters and operation return types. CORBA_IDLType_var ir_current_; // Holder for the IR object most recently created or looked up by // the visitor. This makes it accessible by visitor methods that // need the result of a call to another visitor method that // creates an IR object. + + AST_Decl *scope_; + // Store the node whose scope (if any) we will be visiting. }; #endif /* TAO_IFR_ADDING_VISITOR_H */ diff --git a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_exception.cpp b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_exception.cpp index f03acb4d0ef..8ae7be9837e 100644 --- a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_exception.cpp +++ b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_exception.cpp @@ -7,7 +7,8 @@ ACE_RCSID(IFR_Service, ifr_adding_visitor_exception, "$Id$") -ifr_adding_visitor_exception::ifr_adding_visitor_exception (void) +ifr_adding_visitor_exception::ifr_adding_visitor_exception (AST_Decl *scope) + : ifr_adding_visitor (scope) { } @@ -35,44 +36,74 @@ ifr_adding_visitor_exception::visit_scope (UTL_Scope *node) AST_Field **f = 0; - // Visit each field. - for (CORBA::ULong i = 0; i < nfields; ++i) + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY { - if (e->field (f, i) != 0) + // Visit each field. + for (CORBA::ULong i = 0; i < nfields; ++i) { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::") - ACE_TEXT ("visit_scope -") - ACE_TEXT (" field node access failed\n") - ), - -1 - ); - } + if (e->field (f, i) != 0) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::") + ACE_TEXT ("visit_scope -") + ACE_TEXT (" field node access failed\n") + ), + -1 + ); + } - if ((*f)->ast_accept (this) == -1) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::") - ACE_TEXT ("visit_scope -") - ACE_TEXT (" failed to accept visitor\n") - ), - -1 - ); - } + AST_Type *ft = (*f)->field_type (); - this->members_[i].name = - CORBA::string_dup ((*f)->local_name ()->get_string ()); + idl_bool defined_here = ft->is_child (this->scope_); - // IfR method create_exception does not use this - it just needs - // to be non-null for marshaling. - this->members_[i].type = - CORBA::TypeCode::_duplicate (CORBA::_tc_void); + // If the struct member is defined in the struct, we have to + // do some visiting - otherwise we can just look up the entry. + if (defined_here) + { + if (ft->ast_accept (this) == -1) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::") + ACE_TEXT ("visit_scope -") + ACE_TEXT (" failed to accept visitor\n") + ), + -1 + ); + } + } + else + { + // Updates ir_current_. + this->get_referenced_type (ft, + ACE_TRY_ENV); + ACE_TRY_CHECK; + } - this->members_[i].type_def = - CORBA_IDLType::_duplicate (this->ir_current_.in ()); + this->members_[i].name = + CORBA::string_dup ((*f)->local_name ()->get_string ()); + + // IfR method create_exception does not use this - it just needs + // to be non-zero for marshaling. + this->members_[i].type = + CORBA::TypeCode::_duplicate (CORBA::_tc_void); + + this->members_[i].type_def = + CORBA_IDLType::_duplicate (this->ir_current_.in ()); + } } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION ( + ACE_ANY_EXCEPTION, + ACE_TEXT ("ifr_adding_visitor_structure::visit_scope") + ); + + return -1; + } + ACE_ENDTRY; return 0; } @@ -92,7 +123,8 @@ ifr_adding_visitor_exception::visit_structure (AST_Structure *node) // If not, create a new entry. if (CORBA::is_nil (prev_def.in ())) { - ifr_adding_visitor_structure visitor (1); + ifr_adding_visitor_structure visitor (node, + 1); int retval = visitor.visit_structure (node); @@ -118,32 +150,23 @@ ifr_adding_visitor_exception::visit_structure (AST_Structure *node) } else { - // There is already an entry in the repository, so just update - // the current IR object holder. + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // This call will take the other branch. + return this->visit_structure (node); + } + this->ir_current_ = CORBA_IDLType::_narrow (prev_def.in (), ACE_TRY_ENV); ACE_TRY_CHECK; - - // Nothing prevents this struct's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before we make a - // call on ir_current_. - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::") - ACE_TEXT ("visit_structure -") - ACE_TEXT (" structure %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } } } ACE_CATCHANY @@ -173,31 +196,23 @@ ifr_adding_visitor_exception::visit_exception (AST_Exception *node) if (!CORBA::is_nil (prev_def.in ())) { - CORBA_ExceptionDef_var except_def = - CORBA_ExceptionDef::_narrow (prev_def.in (), - ACE_TRY_ENV); - ACE_TRY_CHECK; + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; - // Nothing prevents this exception's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here. - if (CORBA::is_nil (except_def.in ())) + // This call will create a new EnumDef entry. + return this->visit_exception (node); + } + else { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::") - ACE_TEXT ("visit_exception -") - ACE_TEXT (" exception %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); + // The node is being referenced in an operation, no action. + return 0; } - - return 0; } if (this->visit_scope (node) == -1) @@ -263,6 +278,8 @@ ifr_adding_visitor_exception::visit_exception (AST_Exception *node) ACE_TRY_CHECK; } } + + node->ifr_added (1); } ACE_CATCHANY { @@ -328,35 +345,28 @@ ifr_adding_visitor_exception::visit_enum (AST_Enum *node) ACE_TRY_CHECK; this->move_queue_.enqueue_tail (tmp); + + node->ifr_added (1); } else { - // There is already an entry in the repository, so just update - // the current IR object holder. + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // This call will take the other branch. + return this->visit_enum (node); + } + this->ir_current_ = CORBA_IDLType::_narrow (prev_def.in (), ACE_TRY_ENV); ACE_TRY_CHECK; - - // Nothing prevents this enum's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before the repository - // gets corrupted. - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::") - ACE_TEXT ("visit_enum -") - ACE_TEXT (" enum %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } } } ACE_CATCHANY @@ -388,7 +398,8 @@ ifr_adding_visitor_exception::visit_union (AST_Union *node) // If not, create a new entry. if (CORBA::is_nil (prev_def.in ())) { - ifr_adding_visitor_union visitor (1); + ifr_adding_visitor_union visitor (node, + 1); int retval = visitor.visit_union (node); @@ -414,32 +425,23 @@ ifr_adding_visitor_exception::visit_union (AST_Union *node) } else { - // There is already an entry in the repository, so just update - // the current IR object holder. + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // This call will take the other branch. + return this->visit_union (node); + } + this->ir_current_ = CORBA_IDLType::_narrow (prev_def.in (), ACE_TRY_ENV); ACE_TRY_CHECK; - - // Nothing prevents this union's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before the repository - // gets corrupted. - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::") - ACE_TEXT ("visit_union -") - ACE_TEXT (" union %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } } } ACE_CATCHANY diff --git a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_exception.h b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_exception.h index df336f3e9f8..92cc2de0315 100644 --- a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_exception.h +++ b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_exception.h @@ -37,7 +37,7 @@ class ifr_adding_visitor_exception : public ifr_adding_visitor // for the case when an exception node is seen in the AST. // public: - ifr_adding_visitor_exception (void); + ifr_adding_visitor_exception (AST_Decl *scope); // Constructor. virtual ~ifr_adding_visitor_exception (void); diff --git a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_operation.cpp b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_operation.cpp index d549fd421f7..c22bf56b2b2 100644 --- a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_operation.cpp +++ b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_operation.cpp @@ -7,8 +7,9 @@ ACE_RCSID(IFR_Service, ifr_adding_visitor_operation, "$Id$") -ifr_adding_visitor_operation::ifr_adding_visitor_operation (void) - : index_ (0) +ifr_adding_visitor_operation::ifr_adding_visitor_operation (AST_Decl *scope) + : ifr_adding_visitor (scope), + index_ (0) { } @@ -85,21 +86,6 @@ ifr_adding_visitor_operation::visit_operation (AST_Operation *node) { ex = ex_iter.item (); - // If we got to visit_operation from a forward declared interface, - // this node may not yet be in the repository. If it is, this - // call will merely update ir_current_. - if (ex->ast_accept (this) == -1) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_operation::") - ACE_TEXT ("visit_operation - AST_Exception failed to ") - ACE_TEXT ("accept visitor\n") - ), - -1 - ); - } - prev_def = be_global->repository ()->lookup_id (ex->repoID (), ACE_TRY_ENV); @@ -146,20 +132,10 @@ ifr_adding_visitor_operation::visit_operation (AST_Operation *node) AST_Type *return_type = node->return_type (); - // If this type already has a repository entry, the call - // will just update the current IR object holder. Otherwise, - // it will create the entry. - if (return_type->ast_accept (this) == -1) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_operation::") - ACE_TEXT ("visit_operation -") - ACE_TEXT (" failed to accept visitor\n") - ), - -1 - ); - } + // Updates ir_current_. + this->get_referenced_type (return_type, + ACE_TRY_ENV); + ACE_TRY_CHECK; // Is the operation oneway? CORBA::OperationMode mode = node->flags () == AST_Operation::OP_oneway @@ -223,34 +199,40 @@ ifr_adding_visitor_operation::visit_argument (AST_Argument *node) AST_Type *arg_type = node->field_type (); - // If this type already has a repository entry, the call - // will just update the current IR object holder. Otherwise, - // it will create the entry. - if (arg_type->ast_accept (this) == -1) + ACE_DECLARE_NEW_CORBA_ENV; + ACE_TRY { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_operation::") - ACE_TEXT ("visit_argument - failed to accept visitor\n") - ), - -1 - ); - } + // Updates ir_current_. + this->get_referenced_type (arg_type, + ACE_TRY_ENV); + ACE_TRY_CHECK; - this->params_[this->index_].type_def = - CORBA_IDLType::_duplicate (this->ir_current_.in ()); + this->params_[this->index_].type_def = + CORBA_IDLType::_duplicate (this->ir_current_.in ()); - // Fortunately, AST_Field::Direction and CORBA_ParameterMode - // are ordered identically. - this->params_[this->index_].mode = - (CORBA::ParameterMode) node->direction (); - // IfR method create_operation does not use this - it just needs - // to be non-null for marshaling. - this->params_[this->index_].type = - CORBA::TypeCode::_duplicate (CORBA::_tc_null); + // Fortunately, AST_Field::Direction and CORBA_ParameterMode + // are ordered identically. + this->params_[this->index_].mode = + (CORBA::ParameterMode) node->direction (); - ++this->index_; + // IfR method create_operation does not use this - it just needs + // to be non-zero for marshaling. + this->params_[this->index_].type = + CORBA::TypeCode::_duplicate (CORBA::_tc_void); + + ++this->index_; + } + ACE_CATCHANY + { + ACE_PRINT_EXCEPTION ( + ACE_ANY_EXCEPTION, + ACE_TEXT ("ifr_adding_visitor_operation::visit_argument") + ); + + return -1; + } + ACE_ENDTRY; return 0; } diff --git a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_operation.h b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_operation.h index 79f76b08e1c..1a774f5b54d 100644 --- a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_operation.h +++ b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_operation.h @@ -37,7 +37,7 @@ class ifr_adding_visitor_operation : public ifr_adding_visitor // for the case when an operation node is seen in the AST. // public: - ifr_adding_visitor_operation (void); + ifr_adding_visitor_operation (AST_Decl *scope); // Constructor. virtual ~ifr_adding_visitor_operation (void); diff --git a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_structure.cpp b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_structure.cpp index 3693581a70f..d8eb9bacc49 100644 --- a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_structure.cpp +++ b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_structure.cpp @@ -7,9 +7,11 @@ ACE_RCSID(IFR_Service, ifr_adding_visitor_structure, "$Id$") ifr_adding_visitor_structure::ifr_adding_visitor_structure ( + AST_Decl *scope, CORBA::Boolean is_nested ) - : is_nested_ (is_nested) + : ifr_adding_visitor (scope), + is_nested_ (is_nested) { } @@ -57,18 +59,21 @@ ifr_adding_visitor_structure::visit_scope (UTL_Scope *node) AST_Type *ft = (*f)->field_type (); - if (ft->node_type () == AST_Decl::NT_struct) - { - CORBA_Contained_var prev_def = - be_global->repository ()->lookup_id (ft->repoID (), - ACE_TRY_ENV); - ACE_TRY_CHECK; + idl_bool defined_here = ft->is_child (this->scope_); - if (CORBA::is_nil (prev_def.in ())) + // If the struct member is defined in the struct, we have to + // do some visiting - otherwise we can just look up the entry. + if (defined_here) + { + if (ft->node_type () == AST_Decl::NT_struct) { - ifr_adding_visitor_structure visitor (1); + // Since the enclosing scope hasn't been created yet, + // we make a special visitor to create this member + // at global scope and move it into the struct later. + ifr_adding_visitor_structure visitor (ft, + 1); - if ((*f)->ast_accept (&visitor) == -1) + if (ft->ast_accept (&visitor) == -1) { ACE_ERROR_RETURN (( LM_ERROR, @@ -92,32 +97,32 @@ ifr_adding_visitor_structure::visit_scope (UTL_Scope *node) } else { - this->ir_current_ = - CORBA_IDLType::_narrow (prev_def.in (), - ACE_TRY_ENV); - ACE_TRY_CHECK; + if (ft->ast_accept (this) == -1) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::") + ACE_TEXT ("visit_scope -") + ACE_TEXT (" failed to accept visitor\n") + ), + -1 + ); + } } } else { - if ((*f)->ast_accept (this) == -1) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::") - ACE_TEXT ("visit_scope -") - ACE_TEXT (" failed to accept visitor\n") - ), - -1 - ); - } + // Updates ir_current_. + this->get_referenced_type (ft, + ACE_TRY_ENV); + ACE_TRY_CHECK; } this->members_[i].name = CORBA::string_dup ((*f)->local_name ()->get_string ()); // IfR method create_struct does not use this - it just needs - // to be non-null for marshaling. + // to be non-zero for marshaling. this->members_[i].type = CORBA::TypeCode::_duplicate (CORBA::_tc_void); @@ -167,7 +172,7 @@ ifr_adding_visitor_structure::visit_structure (AST_Structure *node) if (this->is_nested_) { this->ir_current_ = - be_global->repository ()->create_struct ( + be_global->holding_scope ()->create_struct ( node->repoID (), node->local_name ()->get_string (), this->gen_version (node), @@ -232,33 +237,28 @@ ifr_adding_visitor_structure::visit_structure (AST_Structure *node) ACE_TRY_CHECK; } } + + node->ifr_added (1); } else { + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // This call will take the other branch. + return this->visit_structure (node); + } + this->ir_current_ = CORBA_IDLType::_narrow (prev_def.in (), ACE_TRY_ENV); ACE_TRY_CHECK; - - // Nothing prevents this struct's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before the repository - // gets corrupted. - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::") - ACE_TEXT ("visit_structure -") - ACE_TEXT (" struct %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } } } ACE_CATCHANY @@ -329,35 +329,28 @@ ifr_adding_visitor_structure::visit_enum (AST_Enum *node) // (which was created at global scope) goes on the // queue to be moved later. this->move_queue_.enqueue_tail (tmp); + + node->ifr_added (1); } else { - // There is already an entry in the repository, so just update - // the current IR object holder. + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // This call will take the other branch. + return this->visit_enum (node); + } + this->ir_current_ = CORBA_IDLType::_narrow (prev_def.in (), ACE_TRY_ENV); ACE_TRY_CHECK; - - // Nothing prevents this enum's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before the repository - // gets corrupted. - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::") - ACE_TEXT ("visit_enum -") - ACE_TEXT (" enum %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } } } ACE_CATCHANY @@ -389,7 +382,8 @@ ifr_adding_visitor_structure::visit_union (AST_Union *node) // If not, create a new entry. if (CORBA::is_nil (prev_def.in ())) { - ifr_adding_visitor_union visitor (1); + ifr_adding_visitor_union visitor (node, + 1); int retval = visitor.visit_union (node); @@ -415,32 +409,23 @@ ifr_adding_visitor_structure::visit_union (AST_Union *node) } else { - // There is already an entry in the repository, so just update - // the current IR object holder. + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // This call will take the other branch. + return this->visit_union (node); + } + this->ir_current_ = CORBA_IDLType::_narrow (prev_def.in (), ACE_TRY_ENV); ACE_TRY_CHECK; - - // Nothing prevents this union's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before the repository - // gets corrupted. - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::") - ACE_TEXT ("visit_union -") - ACE_TEXT (" union %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } } } ACE_CATCHANY diff --git a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_structure.h b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_structure.h index 7e9c139aba7..6e14fa62395 100644 --- a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_structure.h +++ b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_structure.h @@ -37,7 +37,8 @@ class ifr_adding_visitor_structure : public ifr_adding_visitor // for the case when a struct or exception node is seen in the AST. // public: - ifr_adding_visitor_structure (CORBA::Boolean is_nested); + ifr_adding_visitor_structure (AST_Decl *scope, + CORBA::Boolean is_nested); // Constructor. virtual ~ifr_adding_visitor_structure (void); diff --git a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_union.cpp b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_union.cpp index 51d3f6c5b19..9b186725902 100644 --- a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_union.cpp +++ b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_union.cpp @@ -7,9 +7,11 @@ ACE_RCSID(IFR_Service, ifr_adding_visitor_union, "$Id$") ifr_adding_visitor_union::ifr_adding_visitor_union ( + AST_Decl *scope, CORBA::Boolean is_nested ) - : is_nested_ (is_nested) + : ifr_adding_visitor (scope), + is_nested_ (is_nested) { } @@ -60,18 +62,21 @@ ifr_adding_visitor_union::visit_scope (UTL_Scope *node) AST_Type *ft = (*f)->field_type (); - if (ft->node_type () == AST_Decl::NT_union) - { - CORBA_Contained_var prev_def = - be_global->repository ()->lookup_id (ft->repoID (), - ACE_TRY_ENV); - ACE_TRY_CHECK; + idl_bool defined_here = ft->is_child (this->scope_); - if (CORBA::is_nil (prev_def.in ())) + // If the struct member is defined in the struct, we have to + // do some visiting - otherwise we can just look up the entry. + if (defined_here) + { + if (ft->node_type () == AST_Decl::NT_union) { - ifr_adding_visitor_union visitor (1); + // Since the enclosing scope hasn't been created yet, + // we make a special visitor to create this member + // at global scope and move it into the struct later. + ifr_adding_visitor_union visitor (ft, + 1); - if ((*f)->ast_accept (&visitor) == -1) + if (ft->ast_accept (&visitor) == -1) { ACE_ERROR_RETURN (( LM_ERROR, @@ -95,25 +100,25 @@ ifr_adding_visitor_union::visit_scope (UTL_Scope *node) } else { - this->ir_current_ = - CORBA_IDLType::_narrow (prev_def.in (), - ACE_TRY_ENV); - ACE_TRY_CHECK; + if (ft->ast_accept (this) == -1) + { + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::") + ACE_TEXT ("visit_scope -") + ACE_TEXT (" failed to accept visitor\n") + ), + -1 + ); + } } } else { - if ((*f)->ast_accept (this) == -1) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::") - ACE_TEXT ("visit_scope -") - ACE_TEXT (" failed to accept visitor\n") - ), - -1 - ); - } + // Updates ir_current_. + this->get_referenced_type (ft, + ACE_TRY_ENV); + ACE_TRY_CHECK; } // Get the case label(s). @@ -187,7 +192,7 @@ ifr_adding_visitor_union::visit_scope (UTL_Scope *node) CORBA::string_dup ((*f)->local_name ()->get_string ()); // IfR method create_union does not use this - it just needs - // to be non-null for marshaling. + // to be non-zero for marshaling. this->members_[index].type = CORBA::TypeCode::_duplicate (CORBA::_tc_void); @@ -225,7 +230,8 @@ ifr_adding_visitor_union::visit_structure (AST_Structure *node) // If not, create a new entry. if (CORBA::is_nil (prev_def.in ())) { - ifr_adding_visitor_structure visitor (1); + ifr_adding_visitor_structure visitor (node, + 1); int retval = visitor.visit_structure (node); @@ -251,32 +257,23 @@ ifr_adding_visitor_union::visit_structure (AST_Structure *node) } else { - // There is already an entry in the repository, so just update - // the current IR object holder. + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // This call will take the other branch. + return this->visit_structure (node); + } + this->ir_current_ = CORBA_IDLType::_narrow (prev_def.in (), ACE_TRY_ENV); ACE_TRY_CHECK; - - // Nothing prevents this struct's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before the repository - // gets corrupted. - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::") - ACE_TEXT ("visit_structure -") - ACE_TEXT (" struct %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } } } ACE_CATCHANY @@ -345,35 +342,28 @@ ifr_adding_visitor_union::visit_enum (AST_Enum *node) // (which was created at global scope) goes on the // queue to be moved later. this->move_queue_.enqueue_tail (tmp); + + node->ifr_added (1); } else { - // There is already an entry in the repository, so just update - // the current IR object holder. + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // This call will take the other branch. + return this->visit_enum (node); + } + this->ir_current_ = CORBA_IDLType::_narrow (prev_def.in (), ACE_TRY_ENV); ACE_TRY_CHECK; - - // Nothing prevents this enum's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before the repository - // gets corrupted. - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::") - ACE_TEXT ("visit_enum -") - ACE_TEXT (" enum %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } } } ACE_CATCHANY @@ -463,7 +453,7 @@ ifr_adding_visitor_union::visit_union (AST_Union *node) if (this->is_nested_) { this->ir_current_ = - be_global->repository ()->create_union ( + be_global->holding_scope ()->create_union ( node->repoID (), node->local_name ()->get_string (), this->gen_version (node), @@ -530,33 +520,28 @@ ifr_adding_visitor_union::visit_union (AST_Union *node) ACE_TRY_CHECK; } } + + node->ifr_added (1); } // if (CORBA::is_nil (...)) else { + // If the line below is true, we are clobbering a previous + // entry (from another IDL file) of another type. In that + // case we do what other ORB vendors do, and destroy the + // original entry, create the new one, and let the user beware. + if (node->ifr_added () == 0) + { + prev_def->destroy (ACE_TRY_ENV); + ACE_TRY_CHECK; + + // This call will take the other branch. + return this->visit_union (node); + } + this->ir_current_ = CORBA_IDLType::_narrow (prev_def.in (), ACE_TRY_ENV); ACE_TRY_CHECK; - - // Nothing prevents this union's repo id from already being - // in the repository as another type, if it came from another - // IDL file whose generated code is not linked to the generated - // code from this IDL file. So we check here before the repository - // gets corrupted. - if (CORBA::is_nil (this->ir_current_.in ())) - { - ACE_ERROR_RETURN (( - LM_ERROR, - ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::") - ACE_TEXT ("visit_union -") - ACE_TEXT (" union %s, in IDL file %s, already entered") - ACE_TEXT (" in repository as a different type\n"), - node->full_name (), - be_global->filename () - ), - -1 - ); - } } } ACE_CATCHANY diff --git a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_union.h b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_union.h index 3dff55316c5..1d546bfdddb 100644 --- a/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_union.h +++ b/TAO/orbsvcs/IFR_Service/ifr_adding_visitor_union.h @@ -37,7 +37,8 @@ class ifr_adding_visitor_union : public ifr_adding_visitor // for the case when a union node is seen in the AST. // public: - ifr_adding_visitor_union (CORBA::Boolean is_nested); + ifr_adding_visitor_union (AST_Decl *scope, + CORBA::Boolean is_nested); // Constructor. virtual ~ifr_adding_visitor_union (void); |