1 //=============================================================================
5 * Specialized interface visitor for AMH generates code that is
6 * specific to AMH interfaces.
8 * @author Darrell Brunsch <brunsch@cs.wustl.edu>
10 //=============================================================================
12 #include "interface.h"
14 be_visitor_amh_interface_sh::be_visitor_amh_interface_sh (
15 be_visitor_context
*ctx
)
16 : be_visitor_interface_sh (ctx
)
20 be_visitor_amh_interface_sh::~be_visitor_amh_interface_sh ()
24 // The node is the original interface node but we 'tweak' with the
25 // local_name and the the operation signatures to generate the AMH
26 // skeleton on the 'fly'.
29 be_visitor_amh_interface_sh::visit_interface (be_interface
*node
)
31 if (node
->srv_hdr_gen () || node
->imported () || node
->is_local ())
36 // Do not generate AMH classes for any sort of implied IDL.
37 if (node
->original_interface () != nullptr)
42 TAO_OutStream
*os
= this->ctx_
->stream ();
43 ACE_CString class_name
;
45 TAO_INSERT_COMMENT (os
);
47 // We shall have a POA_ prefix only if we are at the topmost level.
48 if (!node
->is_nested ())
51 class_name
+= "POA_AMH_";
52 class_name
+= node
->local_name ();
57 class_name
+= node
->local_name ();
60 // Generate the skeleton class name.
61 *os
<< "class " << class_name
.c_str () << ";" << be_nl
;
63 // Generate the _ptr declaration.
64 *os
<< "typedef " << class_name
.c_str () << " *" << class_name
.c_str ()
65 << "_ptr;" << be_nl_2
;
67 // Now generate the class definition.
68 *os
<< "class " << be_global
->skel_export_macro ()
69 << " " << class_name
.c_str () << be_idt_nl
<< ": " << be_idt
;
71 long n_parents
= node
->n_inherits ();
75 for (int i
= 0; i
< n_parents
; ++i
)
77 ACE_CString
amh_name ("POA_");
79 // @@ The following code is *NOT* exception-safe.
82 dynamic_cast<be_interface
*> (node
->inherits ()[i
]);
83 base
->compute_full_name ("AMH_", "", buf
);
85 // buf was allocated by ACE_OS::strdup, so we need to use free
94 *os
<< "public virtual "
101 // We don't inherit from another user defined object, hence our
102 // base class is the ServantBase class.
103 *os
<< "public virtual PortableServer::ServantBase";
106 *os
<< be_uidt
<< be_uidt_nl
108 << "protected:" << be_idt_nl
109 << class_name
.c_str () << " ();" << be_uidt_nl
<< be_nl
110 << "public:" << be_idt_nl
;
112 // No copy constructor for locality constraint interface.
113 *os
<< class_name
.c_str () << " (const " << class_name
.c_str ()
114 << "& rhs);" << be_nl
115 << "virtual ~" << class_name
.c_str () << " () = default;\n\n"
117 << "virtual ::CORBA::Boolean _is_a (const char* logical_type_id);" << be_nl_2
;
119 // Add the dispatch method.
120 *os
<< "virtual void _dispatch (" << be_idt
<< be_idt_nl
121 << "TAO_ServerRequest &req," << be_nl
122 << "TAO::Portable_Server::Servant_Upcall *_servant_upcall);" << be_uidt
123 << be_uidt_nl
<< be_nl
;
125 this->this_method (node
);
127 // The _interface_repository_id method.
129 << "virtual const char* _interface_repository_id "
132 if (this->visit_scope (node
) == -1)
134 ACE_ERROR_RETURN ((LM_ERROR
,
135 "(%N:%l) be_visitor_amh_interface_sh::"
137 "codegen for scope failed\n"),
148 be_visitor_amh_interface_sh::visit_operation (be_operation
*node
)
150 be_visitor_amh_operation_sh
visitor (this->ctx_
);
151 return visitor
.visit_operation (node
);
155 be_visitor_amh_interface_sh::visit_attribute (be_attribute
*node
)
157 be_visitor_amh_operation_sh
visitor (this->ctx_
);
158 return visitor
.visit_attribute (node
);
162 be_visitor_amh_interface_sh::add_original_members (be_interface
*node
,
163 be_interface
*amh_node
)
165 if (!node
|| !amh_node
)
170 this->elem_number_
= 0;
172 for (UTL_ScopeActiveIterator
si (node
, UTL_Scope::IK_decls
);
176 AST_Decl
*d
= si
.item ();
182 "(%N:%l) be_visitor_amh_pre_proc::visit_interface - "
183 "bad node in this scope\n"
189 if (d
->node_type () == AST_Decl::NT_attr
)
191 be_attribute
*attribute
= dynamic_cast<be_attribute
*> (d
);
200 be_operation
* operation
= dynamic_cast<be_operation
*> (d
);
204 this->add_amh_operation (operation
, amh_node
);
214 be_visitor_amh_interface_sh::add_amh_operation (be_operation
*node
,
215 be_interface
*amh_node
)
217 if (!node
|| !amh_node
)
222 // We do nothing for oneways!
223 if (node
->flags () == AST_Operation::OP_oneway
)
228 Identifier
*id
= nullptr;
229 UTL_ScopedName
*sn
= nullptr;
240 // Create the return type, which is "void"
241 be_predefined_type
*rt
= nullptr;
243 be_predefined_type (AST_PredefinedType::PT_void
,
247 ACE_CString
original_op_name (
248 node
->name ()->last_component ()->get_string ()
251 UTL_ScopedName
*op_name
=
252 static_cast<UTL_ScopedName
*> (amh_node
->name ()->copy ());
255 Identifier (original_op_name
.rep ()),
265 // Create the operation
266 be_operation
*operation
= nullptr;
267 ACE_NEW_RETURN (operation
,
268 be_operation (rt
, //node->return_type (),
269 AST_Operation::OP_noflags
,
275 operation
->set_name (op_name
);
277 // Iterate over the arguments and put all the in and inout
278 // into the new method.
279 if (node
->nmembers () > 0)
281 // Initialize an iterator to iterate thru our scope.
282 for (UTL_ScopeActiveIterator
si (node
, UTL_Scope::IK_decls
);
286 AST_Decl
*d
= si
.item ();
290 operation
->destroy ();
294 ACE_ERROR_RETURN ((LM_ERROR
,
295 ACE_TEXT ("be_visitor_amh_pre_proc::")
296 ACE_TEXT ("create_response_handler_operation - ")
297 ACE_TEXT ("bad node in this scope\n")),
301 AST_Argument
*original_arg
=
302 dynamic_cast<AST_Argument
*> (d
);
304 if (original_arg
->direction () == AST_Argument::dir_INOUT
||
305 original_arg
->direction () == AST_Argument::dir_IN
)
307 // Create the argument.
308 be_argument
*arg
= nullptr;
310 be_argument (original_arg
->direction (),
311 original_arg
->field_type (),
312 original_arg
->name ()),
315 operation
->be_add_argument (arg
);
320 operation
->set_defined_in (amh_node
);
322 // After having generated the operation we insert it into the
323 // AMH node interface.
324 if (nullptr == amh_node
->be_add_operation (operation
))
334 be_visitor_amh_interface_sh::create_amh_class (ACE_CString name
)
336 Identifier
*id
= nullptr;
338 Identifier (name
.c_str ()),
341 UTL_ScopedName
*amh_class_name
= nullptr;
342 ACE_NEW_RETURN (amh_class_name
,
347 be_interface
*amh_class
= nullptr;
348 ACE_NEW_RETURN (amh_class
,
349 be_interface (amh_class_name
, // name
350 nullptr, // list of inherited
351 0, // number of inherited
352 nullptr, // list of ancestors
353 0, // number of ancestors
358 amh_class
->set_name (amh_class_name
);
363 be_visitor_amh_interface_sh::this_method (be_interface
*node
)
365 TAO_OutStream
*os
= this->ctx_
->stream ();
367 ACE_CString non_amh_name
= node
->client_enclosing_scope ();
368 non_amh_name
+= node
->local_name ();
370 // Print out the _this() method. The _this() method for AMH
371 // interfaces is "special", because the returned type is not exactly
372 // the type of the class, but the original class that "implied" the
374 *os
<< non_amh_name
.c_str () << " *_this ();\n" << be_uidt
;