1 //=============================================================================
3 * @file interface_cs.cpp
5 * Visitor generating code for Interfaces in the client stubs file.
7 * @author Aniruddha Gokhale
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 ()
23 be_visitor_interface_cs::visit_interface (be_interface
*node
)
25 if (node
->imported () || node
->cli_stub_gen ())
30 be_type
*bt
= nullptr;
32 // Set the right type.
33 if (this->ctx_
->alias ())
35 bt
= this->ctx_
->alias ();
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 ();
52 << "// Traits specializations for " << node
->name () << ".";
55 << node
->name () << "_ptr" << be_nl
56 << "TAO::Objref_Traits<" << node
->name () << ">::duplicate ("
57 << node
->name () << "_ptr p)" << be_nl
59 << "return " << node
->name () << "::_duplicate (p);" << be_uidt_nl
64 << "TAO::Objref_Traits<" << node
->name () << ">::release ("
65 << node
->name () << "_ptr p)" << be_nl
68 if (node
->has_mixed_parentage ())
70 *os
<< "::CORBA::AbstractBase_ptr abs = p;" << be_nl
71 << "::CORBA::release (abs);" << be_uidt_nl
;
75 *os
<< "::CORBA::release (p);" << be_uidt_nl
;
81 << node
->name () << "_ptr" << be_nl
82 << "TAO::Objref_Traits<" << node
->name () << ">::nil ()"
85 << "return " << node
->name () << "::_nil ();" << be_uidt_nl
89 << "::CORBA::Boolean" << be_nl
90 << "TAO::Objref_Traits<" << node
->name () << ">::marshal ("
91 << "const " << node
->name () << "_ptr p,"
92 << "TAO_OutputCDR & cdr)" << be_nl
97 if (node
->is_abstract () || c
!= nullptr)
103 *os
<< "::CORBA::Object::marshal (p, cdr);";
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)
116 << "CORBA::Boolean" << be_nl
117 << "CORBA::Policy::_tao_encode (TAO_OutputCDR &)" << 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
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
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
134 << " return TAO_POLICY_DEFAULT_SCOPE;" << be_nl
138 if (be_global
->gen_ostream_operators ())
141 << "std::ostream &" << be_nl
142 << node
->name () << "::_tao_stream_v (std::ostream &strm) const"
145 << "return strm << \"\\\"" << node
->repoID () << "\\\"\";"
150 if (node
->has_mixed_parentage ())
154 << "CORBA::release ("
156 << "_ptr p)" << be_nl
158 << "::CORBA::AbstractBase_ptr abs = p;" << be_nl
159 << "::CORBA::release (abs);" << be_uidt_nl
163 << "::CORBA::Boolean" << be_nl
166 << "_ptr p)" << be_nl
168 << "::CORBA::Object_ptr obj = p;" << be_nl
169 << "return ::CORBA::is_nil (obj);" << be_uidt_nl
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")),
183 if (node
->is_local ())
186 << node
->name () << "::" << node
->local_name ()
191 if (! node
->is_abstract () && ! node
->is_local ())
194 << node
->name () << "::" << node
->local_name ()
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
210 << "::_tao_any_destructor (void *_tao_void_pointer)" << be_nl
212 << node
->local_name () << " *_tao_tmp_pointer =" << be_idt_nl
214 << node
->local_name () << " *> (_tao_void_pointer);" << be_uidt_nl
215 << "::CORBA::release (_tao_tmp_pointer);" << be_uidt_nl
219 if (node
->has_mixed_parentage ())
221 *os
<< "void" << be_nl
222 << node
->name () << "::_add_ref ()" << be_nl
224 << "this->::CORBA::Object::_add_ref ();"
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")),
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")),
251 *os
<< node
->full_name () << "_ptr" << be_nl
252 << node
->full_name () << "::_nil ()"
255 << "return nullptr;" << be_uidt_nl
258 // The _duplicate method
259 *os
<< node
->full_name () << "_ptr" << be_nl
260 << node
->full_name () << "::_duplicate ("
262 << "_ptr obj)" << be_nl
264 << "if (! ::CORBA::is_nil (obj))" << be_idt_nl
266 << "obj->_add_ref ();" << be_uidt_nl
268 << "return obj;" << be_uidt_nl
271 // The _tao_release method
274 *os
<< "void" << be_nl
275 << node
->full_name () << "::_tao_release ("
277 << "_ptr obj)" << be_nl
279 << "::CORBA::release (obj);" << be_uidt_nl
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
);
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")),
300 *os
<< ")" << be_uidt_nl
302 << "return true; // success using local knowledge" << be_uidt_nl
304 << "else" << be_idt_nl
307 if (node
->is_abstract () || node
->is_local ())
309 *os
<< "return false;" << be_uidt_nl
;
313 *os
<< "return this->::CORBA::Object::_is_a (value);" << be_uidt_nl
;
316 *os
<< "}" << be_uidt
<< be_uidt_nl
319 *os
<< "const char* " << node
->full_name ()
320 << "::_interface_repository_id () const"
323 << "return \"" << node
->repoID ()
324 << "\";" << be_uidt_nl
327 if (be_global
->gen_static_desc_operations ())
329 *os
<< be_nl_2
<< "const char* " << node
->full_name ()
330 << "::_desc_repository_id ()"
333 << "return \"" << node
->repoID ()
334 << "\";" << be_uidt_nl
337 *os
<< be_nl_2
<< "const char* " << node
->full_name ()
338 << "::_desc_interface_name ()"
341 << "return \"" << node
->local_name()
342 << "\";" << be_uidt_nl
346 bool const is_loc
= node
->is_local ();
349 << "::CORBA::Boolean" << be_nl
350 << node
->name () << "::marshal (TAO_OutputCDR &"
351 << (is_loc
? " /* " : "") << "cdr"
352 << (is_loc
? " */" : "") << ")" << be_nl
355 << (is_loc
? "false" : "(cdr << this)")
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")),
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")),
400 be_visitor_interface_cs::gen_xxx_narrow (const char *pre
,
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";
414 *os
<< "::CORBA::Object_ptr";
417 *os
<< " _tao_objref)"
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));"
428 << be_uidt
<< be_uidt_nl
433 else if (be_global
->gen_smart_proxies () &&
434 !node
->is_abstract ())
436 *os
<< node
->full_name () << " *proxy = 0;"
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)
447 << "\"" << node
->repoID () << "\"";
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
462 if (!node
->is_abstract ())
464 *os
<< "TAO::Narrow_Utils<"
465 << node
->local_name () << ">::" << pre
<< " (";
469 *os
<< "TAO::AbstractBase_Narrow_Utils<"
470 << node
->local_name () << ">::" << pre
<<" (";
473 *os
<< "_tao_objref";
475 if (ACE_OS::strcmp (pre
, "narrow") == 0)
478 << "\"" << node
->repoID () << "\"";
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 ());
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")),
526 /// Reset port prefix string.
527 this->ctx_
->port_prefix () = "";
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 ());
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")),
555 /// Reset port prefix string.
556 this->ctx_
->port_prefix () = "";
561 be_visitor_interface_cs::gen_abstract_ops_helper (be_interface
*node
,
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 ())
572 AST_Decl
*d
= nullptr;
573 be_visitor_context ctx
;
576 for (UTL_ScopeActiveIterator
si (base
, UTL_Scope::IK_decls
);
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"),
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 (),
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 ());