diff options
Diffstat (limited to 'TAO_IDL/ast/ast_visitor_tmpl_module_ref.cpp')
-rw-r--r-- | TAO_IDL/ast/ast_visitor_tmpl_module_ref.cpp | 58 |
1 files changed, 49 insertions, 9 deletions
diff --git a/TAO_IDL/ast/ast_visitor_tmpl_module_ref.cpp b/TAO_IDL/ast/ast_visitor_tmpl_module_ref.cpp index 172f4d6fcc3..1a05135ffc4 100644 --- a/TAO_IDL/ast/ast_visitor_tmpl_module_ref.cpp +++ b/TAO_IDL/ast/ast_visitor_tmpl_module_ref.cpp @@ -32,13 +32,21 @@ int ast_visitor_tmpl_module_ref::visit_template_module_ref ( AST_Template_Module_Ref *node) { - // This mehod is an override of the base class, and creates + /// This traversal should be done only once. If the template + /// module this ref is contained in is itself aliased later, + /// we don't want to execute the steps below again. + if (node->processed ()) + { + return 0; + } + + // This method is an override of the base class, and creates // the necessary implied IDL in the template module. // Later, the base class visitor then skips the alias and // processes the implied IDL. It's a bit inefficient to have // the implied IDL in both the template module and its // instantiations, but otherwise the lookup issues are - // extremely complicated. This approach allows + // extremely complicated. This approach allows // lookup_by_name_local() to just skip over the alias and // match the module of the same name occurring later in the // template module scope. From that vantage point, the @@ -47,19 +55,43 @@ ast_visitor_tmpl_module_ref::visit_template_module_ref ( // module scope (see ast_visitor_reifying::check_and_store() // and ast_visitor_reifying::template_module_rel_name()). UTL_ScopedName sn (node->local_name (), 0); - + AST_Module *added_module = idl_global->gen ()->create_module (idl_global->scopes (). top (), &sn); - + + added_module->from_ref (node); + added_module->from_inst (this->tmi_); + idl_global->scopes ().top ()->add_to_scope (added_module); - + idl_global->scopes ().push (added_module); - + + /// Replace the current param list (from the reference) with + /// the the list from the referenced template module, since + /// that's what will be search for any matches. We save the + /// current list to restore after the traversal. + + if (idl_global->for_new_holder () == 0) + { + idl_global->for_new_holder ( + const_cast<UTL_StrList *> ( + node->param_refs ())); + } + + UTL_StrList const *old_refs = idl_global->alias_params (); + FE_Utils::T_PARAMLIST_INFO const *old_params = + idl_global->current_params (); + + idl_global->alias_params ( + const_cast<UTL_StrList *> (node->param_refs ())); + AST_Template_Module *tm = node->ref (); + idl_global->current_params (tm->template_params ()); + // Visit the scope of referenced template module. No need to // update the template parameter list since its param list has // to be a subset of the one we're in. - if (this->visit_scope (node->ref ()) != 0) + if (this->visit_scope (tm) != 0) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("ast_visitor_tmpl_module_ref::") @@ -67,9 +99,17 @@ ast_visitor_tmpl_module_ref::visit_template_module_ref ( ACE_TEXT ("visit_scope failed\n")), -1); } - + + /// Restore the global param list state. + idl_global->current_params ( + const_cast<FE_Utils::T_PARAMLIST_INFO *> ( + old_params)); + idl_global->for_new_holder (0); + idl_global->alias_params (const_cast<UTL_StrList *> (old_refs)); + idl_global->scopes ().pop (); - + + node->processed (true); return 0; } |