Use =default for skeleton copy constructor
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_interface / interface_ss.cpp
blob61552287df5f5a560d2d53ff985f0759a9a52855
2 //=============================================================================
3 /**
4 * @file interface_ss.cpp
6 * Visitor generating code for Interfaces in the server skeletons file.
8 * @author Aniruddha Gokhale
9 */
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 ()
26 int
27 be_visitor_interface_ss::visit_interface (be_interface *node)
29 if (node->srv_skel_gen ()
30 || node->imported ()
31 || node->is_abstract ())
33 return 0;
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);
45 return 0;
48 if (this->generate_amh_classes (node) == -1)
50 return -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 ();
62 int status =
63 node->gen_operation_table (flat_name,
64 full_skel_name);
66 if (status == -1)
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")),
73 -1);
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")),
82 -1);
85 TAO_OutStream *os = this->ctx_->stream ();
87 *os << be_nl_2;
89 TAO_INSERT_COMMENT (os);
91 *os << be_nl_2;
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
95 // each case.
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
110 << " ()";
112 if (node->nmembers () == 0)
114 *os << be_idt_nl << ": TAO_ServantBase ()" << be_uidt_nl;
116 else
118 *os << be_nl;
121 // Default constructor body.
122 *os << "{" << be_idt_nl
123 << "this->optable_ = std::addressof (tao_" << flat_name
124 << "_optable);" << be_uidt_nl
125 << "}" << be_nl_2;
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")),
134 -1);
137 *os << be_nl_2;
139 TAO_INSERT_COMMENT (os);
141 *os << be_nl_2;
143 // Generate code for the _is_a override.
144 *os << be_nl_2
145 << "::CORBA::Boolean " << full_skel_name
146 << "::_is_a (const char* value)" << be_nl
147 << "{" << be_idt_nl
148 << "return" << be_idt_nl
149 << "(" << 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")),
158 -1);
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";
169 *os << be_uidt_nl
170 << ");" << be_uidt << be_uidt_nl
171 << "}" << be_nl_2;
173 *os << "const char* " << full_skel_name
174 << "::_interface_repository_id () const"
175 << be_nl;
176 *os << "{" << be_idt_nl;
177 *os << "return \"" << node->repoID () << "\";" << be_uidt_nl;
178 *os << "}";
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")),
200 -1);
203 // AMH generation reuses this visit_interface(), hence the flag.
204 node->tie_skel_gen (true);
207 return 0;
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 (
224 be_interface *node,
225 be_interface *base,
226 TAO_OutStream *os)
228 if (!base->is_abstract ())
230 return 0;
233 AST_Decl *d = nullptr;
234 be_visitor_context ctx;
235 ctx.stream (os);
236 ctx.state (TAO_CodeGen::TAO_ROOT_SS);
238 for (UTL_ScopeActiveIterator si (base, UTL_Scope::IK_decls);
239 !si.is_done ();
240 si.next ())
242 d = si.item ();
244 if (d == nullptr)
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")),
250 -1);
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 (),
262 nullptr),
263 -1);
265 new_name = (UTL_ScopedName *) node->name ()->copy ();
266 new_name->nconc (item_new_name);
268 else
270 continue;
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 (),
298 attr->field_type (),
299 nullptr,
300 attr->is_local (),
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);
324 new_attr.destroy ();
328 return 0;
331 void
332 be_visitor_interface_ss::this_method (be_interface *node)
334 TAO_OutStream *os = this->ctx_->stream ();
336 *os << be_nl_2;
338 TAO_INSERT_COMMENT (os);
340 *os << be_nl_2;
342 // The _this () operation.
343 *os << node->full_name () << " *" << be_nl
344 << node->full_skel_name ()
345 << "::_this ()" << be_nl
346 << "{" << be_idt_nl
347 << "TAO_Stub_Auto_Ptr stub (this->_create_stub ());"
348 << be_nl;
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
359 << "{" << be_idt_nl;
361 *os << "(void) stub.release ();" << be_nl
362 << "return "
363 << "TAO::Narrow_Utils<::" << node->name () << ">::unchecked_narrow ("
364 << "obj.in ());";
366 *os << be_uidt_nl
367 << "}"
368 << be_uidt_nl << "return {};" << be_uidt_nl << "}";
371 void
372 be_visitor_interface_ss::dispatch_method (be_interface *node)
374 TAO_OutStream *os = this->ctx_->stream ();
376 *os << be_nl_2;
378 TAO_INSERT_COMMENT (os);
380 *os << be_nl_2;
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)"
386 << be_uidt_nl;
387 *os << "{" << be_idt_nl;
388 *os << "this->synchronous_upcall_dispatch (req, servant_upcall, this);"
389 << be_uidt_nl;
390 *os << "}";
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);
405 return 0;
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")),
424 -1);
428 return 0;
431 ACE_CString
432 be_visitor_interface_ss::generate_flat_name (be_interface *node)
434 return ACE_CString (node->flat_name ());
437 ACE_CString
438 be_visitor_interface_ss::generate_local_name (be_interface *node)
440 return ACE_CString (node->local_name ());
443 ACE_CString
444 be_visitor_interface_ss::generate_full_skel_name (be_interface *node)
446 return ACE_CString (node->full_skel_name ());