2 //=============================================================================
4 * @file interface_ss.cpp
6 * Visitor generating code for Interfaces in the server skeletons file.
8 * @author Aniruddha Gokhale
10 //=============================================================================
12 #include "interface.h"
13 #include "global_extern.h"
14 #include "ast_generator.h"
15 #include "ast_string.h"
17 be_visitor_interface_ss::be_visitor_interface_ss (be_visitor_context
*ctx
)
18 : be_visitor_interface (ctx
)
22 be_visitor_interface_ss::~be_visitor_interface_ss ()
27 be_visitor_interface_ss::visit_interface (be_interface
*node
)
29 if (node
->srv_skel_gen ()
31 || node
->is_abstract ())
36 if (node
->is_local ())
38 if (this->is_amh_rh_node (node
))
40 // Create amh_rh_visitors.
41 be_visitor_amh_rh_interface_ss
amh_rh_ss_intf (this->ctx_
);
42 amh_rh_ss_intf
.visit_interface (node
);
48 if (this->generate_amh_classes (node
) == -1)
52 ACE_CString full_skel_name_holder
=
53 this->generate_full_skel_name (node
);
55 const char *full_skel_name
= full_skel_name_holder
.c_str ();
57 ACE_CString flat_name_holder
=
58 this->generate_flat_name (node
);
60 const char *flat_name
= flat_name_holder
.c_str ();
63 node
->gen_operation_table (flat_name
,
68 ACE_ERROR_RETURN ((LM_ERROR
,
69 ACE_TEXT ("be_visitor_interface_ss::")
70 ACE_TEXT ("visit_interface - ")
71 ACE_TEXT ("codegen for operation ")
72 ACE_TEXT ("table failed\n")),
76 if (this->generate_proxy_classes (node
) == -1)
78 ACE_ERROR_RETURN ((LM_ERROR
,
79 ACE_TEXT ("be_visitor_interface_ss::")
80 ACE_TEXT ("visit_interface - ")
81 ACE_TEXT ("codegen for proxy classes\n")),
85 TAO_OutStream
*os
= this->ctx_
->stream ();
89 TAO_INSERT_COMMENT (os
);
93 // Find if we are at the top scope or inside some module,
94 // pre-compute the prefix that must be added to the local name in
96 const char *local_name_prefix
= "";
98 if (!node
->is_nested ())
100 local_name_prefix
= "POA_";
103 ACE_CString node_local_name_holder
=
104 this->generate_local_name (node
);
106 const char *node_local_name
= node_local_name_holder
.c_str ();
108 *os
<< full_skel_name
<< "::"
109 << local_name_prefix
<< node_local_name
112 if (node
->nmembers () == 0)
114 *os
<< be_idt_nl
<< ": TAO_ServantBase ()" << be_uidt_nl
;
121 // Default constructor body.
122 *os
<< "{" << be_idt_nl
123 << "this->optable_ = std::addressof (tao_" << flat_name
124 << "_optable);" << be_uidt_nl
127 // Generate code for elements in the scope (e.g., operations).
128 if (this->visit_scope (node
) == -1)
130 ACE_ERROR_RETURN ((LM_ERROR
,
131 ACE_TEXT ("be_visitor_interface_ss::")
132 ACE_TEXT ("visit_interface - ")
133 ACE_TEXT ("codegen for scope failed\n")),
139 TAO_INSERT_COMMENT (os
);
143 // Generate code for the _is_a override.
145 << "::CORBA::Boolean " << full_skel_name
146 << "::_is_a (const char* value)" << be_nl
148 << "return" << be_idt_nl
151 if (node
->traverse_inheritance_graph (be_interface::is_a_helper
, os
) == -1)
153 ACE_ERROR_RETURN ((LM_ERROR
,
154 ACE_TEXT ("be_visitor_interface_ss::")
155 ACE_TEXT ("visit_interface - ")
156 ACE_TEXT ("traversal of inhertance ")
157 ACE_TEXT ("graph failed\n")),
161 *os
<< "std::strcmp (value, \"IDL:omg.org/CORBA/Object:1.0\") == 0";
163 if (node
->has_mixed_parentage ())
165 *os
<< " ||" << be_nl
166 << "std::strcmp (value, \"IDL:omg.org/CORBA/AbstractBase:1.0\") == 0";
170 << ");" << be_uidt
<< be_uidt_nl
173 *os
<< "const char* " << full_skel_name
174 << "::_interface_repository_id () const"
176 *os
<< "{" << be_idt_nl
;
177 *os
<< "return \"" << node
->repoID () << "\";" << be_uidt_nl
;
180 // Print out dispatch method.
181 this->dispatch_method (node
);
183 this->this_method (node
);
185 if (be_global
->gen_tie_classes () && !node
->tie_skel_gen ())
187 // Generate the TIE class.
188 be_visitor_context
ctx (*this->ctx_
);
189 ctx
.state (TAO_CodeGen::TAO_ROOT_TIE_SS
);
190 ctx
.stream (tao_cg
->server_template_skeletons ());
191 be_visitor_interface_tie_ss
visitor (&ctx
);
193 if (node
->accept (&visitor
) == -1)
195 ACE_ERROR_RETURN ((LM_ERROR
,
196 ACE_TEXT ("be_visitor_interface_ss::")
197 ACE_TEXT ("visit_interface - ")
198 ACE_TEXT ("codegen for TIE ")
199 ACE_TEXT ("class failed\n")),
203 // AMH generation reuses this visit_interface(), hence the flag.
204 node
->tie_skel_gen (true);
211 be_visitor_interface_ss::visit_component (be_component
*node
)
213 return this->visit_interface (node
);
217 be_visitor_interface_ss::visit_connector (be_connector
*node
)
219 return this->visit_interface (node
);
223 be_visitor_interface_ss::gen_abstract_ops_helper (
228 if (!base
->is_abstract ())
233 AST_Decl
*d
= nullptr;
234 be_visitor_context ctx
;
236 ctx
.state (TAO_CodeGen::TAO_ROOT_SS
);
238 for (UTL_ScopeActiveIterator
si (base
, UTL_Scope::IK_decls
);
246 ACE_ERROR_RETURN ((LM_ERROR
,
247 ACE_TEXT ("be_visitor_interface_ss::")
248 ACE_TEXT ("gen_abstract_ops_helper - ")
249 ACE_TEXT ("bad node in this scope\n")),
253 AST_Decl::NodeType nt
= d
->node_type ();
255 UTL_ScopedName
*item_new_name
= nullptr;
256 UTL_ScopedName
*new_name
= nullptr;
258 if (AST_Decl::NT_op
== nt
|| AST_Decl::NT_attr
== nt
)
260 ACE_NEW_RETURN (item_new_name
,
261 UTL_ScopedName (d
->local_name ()->copy (),
265 new_name
= (UTL_ScopedName
*) node
->name ()->copy ();
266 new_name
->nconc (item_new_name
);
273 // We pass the node's is_abstract flag to the operation
274 // constructor so we will get the right generated operation
275 // body if we are regenerating an operation from an
276 // abstract interface in a concrete interface or component.
277 if (AST_Decl::NT_op
== nt
)
279 be_operation
*op
= dynamic_cast<be_operation
*> (d
);
280 UTL_ScopedName
*old_name
=
281 (UTL_ScopedName
*) op
->name ()->copy ();
282 op
->set_name (new_name
);
283 op
->set_defined_in (node
);
284 op
->is_abstract (node
->is_abstract ());
286 be_visitor_operation_ss
op_visitor (&ctx
);
287 op_visitor
.visit_operation (op
);
289 op
->set_name (old_name
);
290 op
->set_defined_in (base
);
291 op
->is_abstract (base
->is_abstract ());
293 else if (AST_Decl::NT_attr
== nt
)
295 AST_Attribute
*attr
=
296 dynamic_cast<AST_Attribute
*> (d
);
297 be_attribute
new_attr (attr
->readonly (),
301 attr
->is_abstract ());
302 new_attr
.set_defined_in (node
);
303 new_attr
.set_name (new_name
);
305 UTL_ExceptList
*get_exceptions
=
306 attr
->get_get_exceptions ();
308 if (nullptr != get_exceptions
)
310 new_attr
.be_add_get_exceptions (get_exceptions
->copy ());
313 UTL_ExceptList
*set_exceptions
=
314 attr
->get_set_exceptions ();
316 if (nullptr != set_exceptions
)
318 new_attr
.be_add_set_exceptions (set_exceptions
->copy ());
321 be_visitor_attribute
attr_visitor (&ctx
);
322 attr_visitor
.visit_attribute (&new_attr
);
323 ctx
.attribute (nullptr);
332 be_visitor_interface_ss::this_method (be_interface
*node
)
334 TAO_OutStream
*os
= this->ctx_
->stream ();
338 TAO_INSERT_COMMENT (os
);
342 // The _this () operation.
343 *os
<< node
->full_name () << " *" << be_nl
344 << node
->full_skel_name ()
345 << "::_this ()" << be_nl
347 << "TAO_Stub_Auto_Ptr stub (this->_create_stub ());"
350 *os
<< "::CORBA::Boolean const _tao_opt_colloc = "
351 << "stub->servant_orb_var ()->orb_core ()->"
352 << "optimize_collocation_objects ();" << be_nl
;
354 /* Coverity whines about an unused return value from _nil() when
355 initializing tmp. Just use zero instead. */
356 *os
<< "::CORBA::Object_var obj = "
357 << "new (std::nothrow) ::CORBA::Object (stub.get (), _tao_opt_colloc, this);" << be_nl
358 << "if (obj.ptr ())" << be_idt_nl
361 *os
<< "(void) stub.release ();" << be_nl
363 << "TAO::Narrow_Utils<::" << node
->name () << ">::unchecked_narrow ("
368 << be_uidt_nl
<< "return {};" << be_uidt_nl
<< "}";
372 be_visitor_interface_ss::dispatch_method (be_interface
*node
)
374 TAO_OutStream
*os
= this->ctx_
->stream ();
378 TAO_INSERT_COMMENT (os
);
382 *os
<< "void " << node
->full_skel_name ()
383 << "::_dispatch (" << be_idt_nl
384 << "TAO_ServerRequest & req," << be_nl
385 << "TAO::Portable_Server::Servant_Upcall* servant_upcall)"
387 *os
<< "{" << be_idt_nl
;
388 *os
<< "this->synchronous_upcall_dispatch (req, servant_upcall, this);"
394 be_visitor_interface_ss::generate_amh_classes (be_interface
*node
)
396 // We have to check for any abstract ancestor until AMH is integrated
397 // with abstract interfaces. If the node itself is abstract, this
398 // visitor would not be created.
399 if (be_global
->gen_amh_classes () && !node
->has_mixed_parentage ())
401 be_visitor_amh_interface_ss
amh_intf (this->ctx_
);
402 return amh_intf
.visit_interface (node
);
409 be_visitor_interface_ss::generate_proxy_classes (be_interface
*node
)
411 if (be_global
->gen_direct_collocation ())
413 be_visitor_context ctx
= *this->ctx_
;
414 ctx
.state (TAO_CodeGen::TAO_INTERFACE_DIRECT_PROXY_IMPL_SS
);
415 be_visitor_interface_direct_proxy_impl_ss
idpi_visitor (&ctx
);
417 if (node
->accept (&idpi_visitor
) == -1)
419 ACE_ERROR_RETURN ((LM_ERROR
,
420 ACE_TEXT ("be_visitor_interface_cs::")
421 ACE_TEXT ("generate_proxy_classes - ")
422 ACE_TEXT ("codegen for Base Proxy ")
423 ACE_TEXT ("Broker class failed\n")),
432 be_visitor_interface_ss::generate_flat_name (be_interface
*node
)
434 return ACE_CString (node
->flat_name ());
438 be_visitor_interface_ss::generate_local_name (be_interface
*node
)
440 return ACE_CString (node
->local_name ());
444 be_visitor_interface_ss::generate_full_skel_name (be_interface
*node
)
446 return ACE_CString (node
->full_skel_name ());