Use =default for skeleton copy constructor
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_interface / interface_cs.cpp
blobb08822dc0900ae05434f8e33d4eb3c17e2e69dc0
1 //=============================================================================
2 /**
3 * @file interface_cs.cpp
5 * Visitor generating code for Interfaces in the client stubs file.
7 * @author Aniruddha Gokhale
8 */
9 //=============================================================================
11 #include "interface.h"
13 be_visitor_interface_cs::be_visitor_interface_cs (be_visitor_context *ctx)
14 : be_visitor_interface (ctx)
18 be_visitor_interface_cs::~be_visitor_interface_cs ()
22 int
23 be_visitor_interface_cs::visit_interface (be_interface *node)
25 if (node->imported () || node->cli_stub_gen ())
27 return 0;
30 be_type *bt = nullptr;
32 // Set the right type.
33 if (this->ctx_->alias ())
35 bt = this->ctx_->alias ();
37 else
39 bt = node;
42 AST_Component *c = dynamic_cast<AST_Component*> (node);
43 TAO_OutStream *os = this->ctx_->stream ();
45 if (node->is_defined () && be_global->gen_arg_traits ())
47 TAO_INSERT_COMMENT (os);
49 *os << be_global->core_versioning_begin ();
51 *os << be_nl
52 << "// Traits specializations for " << node->name () << ".";
54 *os << be_nl_2
55 << node->name () << "_ptr" << be_nl
56 << "TAO::Objref_Traits<" << node->name () << ">::duplicate ("
57 << node->name () << "_ptr p)" << be_nl
58 << "{" << be_idt_nl
59 << "return " << node->name () << "::_duplicate (p);" << be_uidt_nl
60 << "}";
62 *os << be_nl_2
63 << "void" << be_nl
64 << "TAO::Objref_Traits<" << node->name () << ">::release ("
65 << node->name () << "_ptr p)" << be_nl
66 << "{" << be_idt_nl;
68 if (node->has_mixed_parentage ())
70 *os << "::CORBA::AbstractBase_ptr abs = p;" << be_nl
71 << "::CORBA::release (abs);" << be_uidt_nl;
73 else
75 *os << "::CORBA::release (p);" << be_uidt_nl;
78 *os << "}";
80 *os << be_nl_2
81 << node->name () << "_ptr" << be_nl
82 << "TAO::Objref_Traits<" << node->name () << ">::nil ()"
83 << be_nl
84 << "{" << be_idt_nl
85 << "return " << node->name () << "::_nil ();" << be_uidt_nl
86 << "}";
88 *os << be_nl_2
89 << "::CORBA::Boolean" << be_nl
90 << "TAO::Objref_Traits<" << node->name () << ">::marshal ("
91 << "const " << node->name () << "_ptr p,"
92 << "TAO_OutputCDR & cdr)" << be_nl
93 << "{" << be_idt_nl
94 << "return ";
97 if (node->is_abstract () || c != nullptr)
99 *os << "cdr << p;";
101 else
103 *os << "::CORBA::Object::marshal (p, cdr);";
106 *os << be_uidt_nl
107 << "}" << be_nl;
109 *os << be_global->core_versioning_end () << be_nl;
112 // If we are generating CORBA Policy we need to add some more methods
113 if (ACE_OS::strcmp (node->full_name (), "CORBA::Policy") == 0)
115 *os << be_nl
116 << "CORBA::Boolean" << be_nl
117 << "CORBA::Policy::_tao_encode (TAO_OutputCDR &)" << be_nl
118 << "{" << be_nl
119 << " return false;" << be_nl
120 << "}" << be_nl << be_nl
121 << "CORBA::Boolean" << be_nl
122 << "CORBA::Policy::_tao_decode (TAO_InputCDR &)" << be_nl
123 << "{" << be_nl
124 << " return false;" << be_nl
125 << "}" << be_nl << be_nl
126 << "TAO_Cached_Policy_Type" << be_nl
127 << "CORBA::Policy::_tao_cached_type () const" << be_nl
128 << "{" << be_nl
129 << "return TAO_CACHED_POLICY_UNCACHED;" << be_nl
130 << "}" << be_nl << be_nl
131 << "TAO_Policy_Scope" << be_nl
132 << "CORBA::Policy::_tao_scope () const" << be_nl
133 << "{" << be_nl
134 << " return TAO_POLICY_DEFAULT_SCOPE;" << be_nl
135 << "}" << be_nl;
138 if (be_global->gen_ostream_operators ())
140 *os << be_nl_2
141 << "std::ostream &" << be_nl
142 << node->name () << "::_tao_stream_v (std::ostream &strm) const"
143 << be_nl
144 << "{" << be_idt_nl
145 << "return strm << \"\\\"" << node->repoID () << "\\\"\";"
146 << be_uidt_nl
147 << "}";
150 if (node->has_mixed_parentage ())
152 *os << be_nl_2
153 << "void" << be_nl
154 << "CORBA::release ("
155 << node->name ()
156 << "_ptr p)" << be_nl
157 << "{" << be_idt_nl
158 << "::CORBA::AbstractBase_ptr abs = p;" << be_nl
159 << "::CORBA::release (abs);" << be_uidt_nl
160 << "}";
162 *os << be_nl_2
163 << "::CORBA::Boolean" << be_nl
164 << "CORBA::is_nil ("
165 << node->name ()
166 << "_ptr p)" << be_nl
167 << "{" << be_idt_nl
168 << "::CORBA::Object_ptr obj = p;" << be_nl
169 << "return ::CORBA::is_nil (obj);" << be_uidt_nl
170 << "}";
173 // Generate code for the elements of the interface.
174 if (this->visit_scope (node) == -1)
176 ACE_ERROR_RETURN ((LM_ERROR,
177 ACE_TEXT ("be_visitor_interface_cs::")
178 ACE_TEXT ("visit_interface - ")
179 ACE_TEXT ("codegen for scope failed\n")),
180 -1);
183 if (node->is_local ())
185 *os << be_nl_2
186 << node->name () << "::" << node->local_name ()
187 << " ()" << be_nl
188 << "{}";
191 if (! node->is_abstract () && ! node->is_local ())
193 *os << be_nl_2
194 << node->name () << "::" << node->local_name ()
195 << " ()" << be_nl;
197 *os << "{" << be_nl;
198 *os << "}" << be_nl;
201 bool gen_any_destructor =
202 be_global->any_support ()
203 && (!node->is_local ()
204 || be_global->gen_local_iface_anyops ());
206 if (gen_any_destructor)
208 *os << "void" << be_nl
209 << node->name ()
210 << "::_tao_any_destructor (void *_tao_void_pointer)" << be_nl
211 << "{" << be_idt_nl
212 << node->local_name () << " *_tao_tmp_pointer =" << be_idt_nl
213 << "static_cast<"
214 << node->local_name () << " *> (_tao_void_pointer);" << be_uidt_nl
215 << "::CORBA::release (_tao_tmp_pointer);" << be_uidt_nl
216 << "}" << be_nl_2;
219 if (node->has_mixed_parentage ())
221 *os << "void" << be_nl
222 << node->name () << "::_add_ref ()" << be_nl
223 << "{" << be_idt_nl
224 << "this->::CORBA::Object::_add_ref ();"
225 << be_uidt_nl
226 << "}" << be_nl_2;
229 // The _narrow method
230 if (! this->gen_xxx_narrow ("narrow", node))
232 ACE_ERROR_RETURN ((LM_ERROR,
233 ACE_TEXT ("be_visitor_interface_cs::")
234 ACE_TEXT ("visit_interface - ")
235 ACE_TEXT ("_narrow () method codegen failed\n")),
236 -1);
239 // The _unchecked_narrow method, not for components.
240 if (c == nullptr && ! this->gen_xxx_narrow ("unchecked_narrow", node))
242 ACE_ERROR_RETURN ((LM_ERROR,
243 ACE_TEXT ("be_visitor_interface_cs::")
244 ACE_TEXT ("visit_interface - ")
245 ACE_TEXT ("_unchecked_narrow () method codegen")
246 ACE_TEXT (" failed\n")),
247 -1);
250 // The _nil method
251 *os << node->full_name () << "_ptr" << be_nl
252 << node->full_name () << "::_nil ()"
253 << be_nl
254 << "{" << be_idt_nl
255 << "return nullptr;" << be_uidt_nl
256 << "}" << be_nl_2;
258 // The _duplicate method
259 *os << node->full_name () << "_ptr" << be_nl
260 << node->full_name () << "::_duplicate ("
261 << bt->local_name ()
262 << "_ptr obj)" << be_nl
263 << "{" << be_idt_nl
264 << "if (! ::CORBA::is_nil (obj))" << be_idt_nl
265 << "{" << be_idt_nl
266 << "obj->_add_ref ();" << be_uidt_nl
267 << "}" << be_uidt_nl
268 << "return obj;" << be_uidt_nl
269 << "}" << be_nl_2;
271 // The _tao_release method
272 if (c == nullptr)
274 *os << "void" << be_nl
275 << node->full_name () << "::_tao_release ("
276 << bt->local_name ()
277 << "_ptr obj)" << be_nl
278 << "{" << be_idt_nl
279 << "::CORBA::release (obj);" << be_uidt_nl
280 << "}" << be_nl_2;
283 *os << "::CORBA::Boolean" << be_nl
284 << node->full_name () << "::_is_a (const char *value)" << be_nl;
286 *os << "{" << be_idt_nl
287 << "if (" << be_idt << be_idt_nl;
289 int status = node->gen_is_a_ancestors (os);
291 if (status == -1)
293 ACE_ERROR_RETURN ((LM_ERROR,
294 ACE_TEXT ("be_visitor_interface_cs::")
295 ACE_TEXT ("visit_interface - ")
296 ACE_TEXT ("gen_is_a_ancestors() failed\n")),
297 -1);
300 *os << ")" << be_uidt_nl
301 << "{" << be_idt_nl
302 << "return true; // success using local knowledge" << be_uidt_nl
303 << "}" << be_uidt_nl
304 << "else" << be_idt_nl
305 << "{" << be_idt_nl;
307 if (node->is_abstract () || node->is_local ())
309 *os << "return false;" << be_uidt_nl;
311 else
313 *os << "return this->::CORBA::Object::_is_a (value);" << be_uidt_nl;
316 *os << "}" << be_uidt << be_uidt_nl
317 << "}" << be_nl_2;
319 *os << "const char* " << node->full_name ()
320 << "::_interface_repository_id () const"
321 << be_nl
322 << "{" << be_idt_nl
323 << "return \"" << node->repoID ()
324 << "\";" << be_uidt_nl
325 << "}";
327 if (be_global->gen_static_desc_operations ())
329 *os << be_nl_2 << "const char* " << node->full_name ()
330 << "::_desc_repository_id ()"
331 << be_nl
332 << "{" << be_idt_nl
333 << "return \"" << node->repoID ()
334 << "\";" << be_uidt_nl
335 << "}";
337 *os << be_nl_2 << "const char* " << node->full_name ()
338 << "::_desc_interface_name ()"
339 << be_nl
340 << "{" << be_idt_nl
341 << "return \"" << node->local_name()
342 << "\";" << be_uidt_nl
343 << "}";
346 bool const is_loc = node->is_local ();
348 *os << be_nl_2
349 << "::CORBA::Boolean" << be_nl
350 << node->name () << "::marshal (TAO_OutputCDR &"
351 << (is_loc ? " /* " : "") << "cdr"
352 << (is_loc ? " */" : "") << ")" << be_nl
353 << "{" << be_idt_nl
354 << "return "
355 << (is_loc ? "false" : "(cdr << this)")
356 << ";" << be_uidt_nl
357 << "}";
359 if (! node->is_abstract ())
361 // Smart Proxy classes.
362 if (! node->is_local () && be_global->gen_smart_proxies ())
364 be_visitor_context ctx (*this->ctx_);
366 ctx.state (TAO_CodeGen::TAO_INTERFACE_SMART_PROXY_CS);
367 be_visitor_interface_smart_proxy_cs isp_visitor (&ctx);
369 if (node->accept (&isp_visitor) == -1)
371 ACE_ERROR_RETURN ((LM_ERROR,
372 ACE_TEXT ("be_visitor_interface_cs::")
373 ACE_TEXT ("visit_interface - ")
374 ACE_TEXT ("codegen for smart ")
375 ACE_TEXT ("proxy classes failed\n")),
376 -1);
381 if (be_global->tc_support ())
383 be_visitor_context ctx = *this->ctx_;
384 TAO::be_visitor_objref_typecode tc_visitor (&ctx);
386 if (node->accept (&tc_visitor) == -1)
388 ACE_ERROR_RETURN ((LM_ERROR,
389 ACE_TEXT ("be_visitor_interface_cs::")
390 ACE_TEXT ("visit_interface - ")
391 ACE_TEXT ("TypeCode definition failed\n")),
392 -1);
396 return 0;
399 bool
400 be_visitor_interface_cs::gen_xxx_narrow (const char *pre,
401 be_interface *node)
403 TAO_OutStream *os = this->ctx_->stream ();
405 *os << node->full_name () << "_ptr" << be_nl
406 << node->full_name () << "::_" << pre << " (";
408 if (node->is_abstract ())
410 *os << "::CORBA::AbstractBase_ptr";
412 else
414 *os << "::CORBA::Object_ptr";
417 *os << " _tao_objref)"
418 << be_nl
419 << "{" << be_idt_nl;
421 if (node->is_local ())
423 *os << "return " << node->local_name ()
424 << "::_duplicate (" << be_idt << be_idt_nl
425 << "dynamic_cast<" << node->local_name ()
426 << "_ptr> (_tao_objref));"
427 << be_uidt
428 << be_uidt << be_uidt_nl
429 << "}" << be_nl_2;
431 return true;
433 else if (be_global->gen_smart_proxies () &&
434 !node->is_abstract ())
436 *os << node->full_name () << " *proxy = 0;"
437 << be_nl_2
438 << "proxy = TAO::Narrow_Utils<"
439 << node->local_name () << ">::" << pre << " (";
441 *os << be_idt << be_idt_nl;
443 *os << "_tao_objref";
444 if (ACE_OS::strcmp (pre, "narrow") == 0)
446 *os << "," << be_nl
447 << "\"" << node->repoID () << "\"";
450 *os << ");";
452 *os << be_uidt << be_uidt << be_nl
453 << "return TAO_" << node->flat_name ()
454 << "_PROXY_FACTORY_ADAPTER::instance ()->create_proxy (proxy);"
455 << be_uidt << be_uidt_nl
456 << "}" << be_nl_2;
458 else
460 *os << "return ";
462 if (!node->is_abstract ())
464 *os << "TAO::Narrow_Utils<"
465 << node->local_name () << ">::" << pre << " (";
467 else
469 *os << "TAO::AbstractBase_Narrow_Utils<"
470 << node->local_name () << ">::" << pre <<" (";
473 *os << "_tao_objref";
475 if (ACE_OS::strcmp (pre, "narrow") == 0)
477 *os << ", "
478 << "\"" << node->repoID () << "\"";
481 *os << ");";
483 *os << be_uidt_nl
484 << "}" << be_nl_2;
487 return true;
491 be_visitor_interface_cs::visit_component (be_component *node)
493 return this->visit_interface (node);
497 be_visitor_interface_cs::visit_connector (be_connector *node)
499 return this->visit_interface (node);
503 be_visitor_interface_cs::visit_extended_port (be_extended_port *node)
505 this->ctx_->port_prefix () = node->local_name ()->get_string ();
506 this->ctx_->port_prefix () += '_';
508 /// If the port visit traverses any attributes defined in the
509 /// original porttype, this is a way for visitors down the
510 /// line to tell what scope we are actually in.
511 this->ctx_->interface (
512 dynamic_cast<be_interface*> (node->defined_in ()));
514 /// Will ignore everything but porttype attributes.
515 int status = this->visit_scope (node->port_type ());
517 if (status == -1)
519 ACE_ERROR_RETURN ((LM_ERROR,
520 ACE_TEXT ("be_visitor_interface_ch")
521 ACE_TEXT ("::visit_extended_port - ")
522 ACE_TEXT ("visit_scope failed\n")),
523 -1);
526 /// Reset port prefix string.
527 this->ctx_->port_prefix () = "";
528 return 0;
532 be_visitor_interface_cs::visit_mirror_port (be_mirror_port *node)
534 this->ctx_->port_prefix () = node->local_name ()->get_string ();
535 this->ctx_->port_prefix () += '_';
537 /// If the port visit traverses any attributes defined in the
538 /// original porttype, this is a way for visitors down the
539 /// line to tell what scope we are actually in.
540 this->ctx_->interface (
541 dynamic_cast<be_interface*> (node->defined_in ()));
543 /// Will ignore everything but porttype attributes.
544 int status = this->visit_scope (node->port_type ());
546 if (status == -1)
548 ACE_ERROR_RETURN ((LM_ERROR,
549 ACE_TEXT ("be_visitor_interface_ch")
550 ACE_TEXT ("::visit_mirror_port - ")
551 ACE_TEXT ("visit_scope failed\n")),
552 -1);
555 /// Reset port prefix string.
556 this->ctx_->port_prefix () = "";
557 return 0;
561 be_visitor_interface_cs::gen_abstract_ops_helper (be_interface *node,
562 be_interface *base,
563 TAO_OutStream *os)
565 // If the derived interface is local, the abstract parent's operation
566 // was generated as pure virtual.
567 if (!base->is_abstract () || node->is_local ())
569 return 0;
572 AST_Decl *d = nullptr;
573 be_visitor_context ctx;
574 ctx.stream (os);
576 for (UTL_ScopeActiveIterator si (base, UTL_Scope::IK_decls);
577 !si.is_done ();
578 si.next ())
580 d = si.item ();
582 if (d == nullptr)
584 ACE_ERROR_RETURN ((LM_ERROR,
585 "(%N:%l) be_visitor_interface_cs::"
586 "gen_abstract_ops_helper - "
587 "bad node in this scope\n"),
588 -1);
591 if (d->node_type () == AST_Decl::NT_op)
593 UTL_ScopedName *item_new_name = nullptr;
594 ACE_NEW_RETURN (item_new_name,
595 UTL_ScopedName (d->local_name ()->copy (),
596 nullptr),
597 -1);
599 UTL_ScopedName *new_op_name =
600 (UTL_ScopedName *)node->name ()->copy ();
601 new_op_name->nconc (item_new_name);
603 be_operation *op = dynamic_cast<be_operation*> (d);
604 UTL_ScopedName *old_op_name =
605 (UTL_ScopedName *) op->name ()->copy ();
606 op->set_name (new_op_name);
607 op->set_defined_in (node);
608 op->is_abstract (node->is_abstract ());
610 ctx.state (TAO_CodeGen::TAO_OPERATION_CS);
611 be_visitor_operation_cs op_visitor (&ctx);
612 op_visitor.visit_operation (op);
614 op->set_name (old_op_name);
615 op->set_defined_in (base);
616 op->is_abstract (base->is_abstract ());
620 return 0;