2 * @file ast_visitor_tmpl_module_ref.cpp
6 //=============================================================================
8 #include "ast_visitor_tmpl_module_ref.h"
9 #include "ast_visitor_context.h"
10 #include "ast_generator.h"
12 #include "ast_module.h"
13 #include "ast_template_module.h"
14 #include "ast_template_module_ref.h"
16 #include "global_extern.h"
17 #include "nr_extern.h"
19 ast_visitor_tmpl_module_ref::ast_visitor_tmpl_module_ref (
20 ast_visitor_context
*ctx
)
21 : ast_visitor_tmpl_module_inst (ctx
, true)
25 ast_visitor_tmpl_module_ref::~ast_visitor_tmpl_module_ref (void)
30 ast_visitor_tmpl_module_ref::visit_template_module_ref (
31 AST_Template_Module_Ref
*node
)
33 /// This traversal should be done only once. If the template
34 /// module this ref is contained in is itself aliased later,
35 /// we don't want to execute the steps below again.
36 if (node
->processed ())
41 // This method is an override of the base class, and creates
42 // the necessary implied IDL in the template module.
43 // Later, the base class visitor then skips the alias and
44 // processes the implied IDL. It's a bit inefficient to have
45 // the implied IDL in both the template module and its
46 // instantiations, but otherwise the lookup issues are
47 // extremely complicated. This approach allows
48 // lookup_by_name_local() to just skip over the alias and
49 // match the module of the same name occurring later in the
50 // template module scope. From that vantage point, the
51 // reifying visitor uses its established mechanism to jump
52 // to the module of the same name in the instantiated template
53 // module scope (see ast_visitor_reifying::check_and_store()
54 // and ast_visitor_reifying::template_module_rel_name()).
55 UTL_ScopedName
sn (node
->local_name (), 0);
57 AST_Module
*added_module
=
58 idl_global
->gen ()->create_module (idl_global
->scopes (). top (),
61 added_module
->from_ref (node
);
62 added_module
->from_inst (this->tmi_
);
64 idl_global
->scopes ().top ()->add_to_scope (added_module
);
66 idl_global
->scopes ().push (added_module
);
68 /// Replace the current param list (from the reference) with
69 /// the the list from the referenced template module, since
70 /// that's what will be search for any matches. We save the
71 /// current list to restore after the traversal.
73 if (idl_global
->for_new_holder () == 0)
75 idl_global
->for_new_holder (
76 const_cast<UTL_StrList
*> (
77 node
->param_refs ()));
80 UTL_StrList
const *old_refs
= idl_global
->alias_params ();
81 FE_Utils::T_PARAMLIST_INFO
const *old_params
=
82 idl_global
->current_params ();
84 idl_global
->alias_params (
85 const_cast<UTL_StrList
*> (node
->param_refs ()));
86 AST_Template_Module
*tm
= node
->ref ();
87 idl_global
->current_params (tm
->template_params ());
89 // Visit the scope of referenced template module. No need to
90 // update the template parameter list since its param list has
91 // to be a subset of the one we're in.
92 if (this->visit_scope (tm
) != 0)
94 ACE_ERROR_RETURN ((LM_ERROR
,
95 ACE_TEXT ("ast_visitor_tmpl_module_ref::")
96 ACE_TEXT ("visit_template_module_ref - ")
97 ACE_TEXT ("visit_scope failed\n")),
101 /// Restore the global param list state.
102 idl_global
->current_params (
103 const_cast<FE_Utils::T_PARAMLIST_INFO
*> (
105 idl_global
->for_new_holder (0);
106 idl_global
->alias_params (const_cast<UTL_StrList
*> (old_refs
));
108 idl_global
->scopes ().pop ();
110 node
->processed (true);