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 ())
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 << be_idt
<< be_idt_nl
58 << node
->name () << "_ptr p)" << be_uidt
<< be_uidt_nl
60 << "return " << node
->name () << "::_duplicate (p);" << be_uidt_nl
65 << "TAO::Objref_Traits<" << node
->name () << ">::release ("
66 << be_idt
<< be_idt_nl
67 << node
->name () << "_ptr p)" << be_uidt
<< be_uidt_nl
70 // Workaround for broken HP V7.4-004 on OpenVMS IA83
71 if (node
->has_mixed_parentage ())
73 *os
<< "::CORBA::AbstractBase_ptr abs = p;" << be_nl
74 << "::CORBA::release (abs);" << be_uidt_nl
;
78 *os
<< "::CORBA::release (p);" << be_uidt_nl
;
84 << node
->name () << "_ptr" << be_nl
85 << "TAO::Objref_Traits<" << node
->name () << ">::nil (void)"
88 << "return " << node
->name () << "::_nil ();" << be_uidt_nl
92 << "::CORBA::Boolean" << be_nl
93 << "TAO::Objref_Traits<" << node
->name () << ">::marshal ("
94 << be_idt
<< be_idt_nl
95 << "const " << node
->name () << "_ptr p," << be_nl
96 << "TAO_OutputCDR & cdr)" << be_uidt
<< be_uidt_nl
101 if (node
->is_abstract () || c
!= 0)
107 *os
<< "::CORBA::Object::marshal (p, cdr);";
113 *os
<< be_global
->core_versioning_end () << be_nl
;
116 // If we are generating CORBA Policy we need to add some more methods
117 if (ACE_OS::strcmp (node
->full_name (), "CORBA::Policy") == 0)
120 << "CORBA::Boolean" << be_nl
121 << "CORBA::Policy::_tao_encode (TAO_OutputCDR &)" << be_nl
123 << " return false;" << be_nl
124 << "}" << be_nl
<< be_nl
125 << "CORBA::Boolean" << be_nl
126 << "CORBA::Policy::_tao_decode (TAO_InputCDR &)" << be_nl
128 << " return false;" << be_nl
129 << "}" << be_nl
<< be_nl
130 << "TAO_Cached_Policy_Type" << be_nl
131 << "CORBA::Policy::_tao_cached_type (void) const" << be_nl
133 << "return TAO_CACHED_POLICY_UNCACHED;" << be_nl
134 << "}" << be_nl
<< be_nl
135 << "TAO_Policy_Scope" << be_nl
136 << "CORBA::Policy::_tao_scope (void) const" << be_nl
138 << " return TAO_POLICY_DEFAULT_SCOPE;" << be_nl
142 if (be_global
->gen_ostream_operators ())
145 << "std::ostream &" << be_nl
146 << node
->name () << "::_tao_stream_v (std::ostream &strm) const"
149 << "return strm << \"\\\"" << node
->repoID () << "\\\"\";"
154 if (node
->has_mixed_parentage ())
158 << "CORBA::release ("
160 << "_ptr p)" << be_nl
162 << "::CORBA::AbstractBase_ptr abs = p;" << be_nl
163 << "::CORBA::release (abs);" << be_uidt_nl
167 << "::CORBA::Boolean" << be_nl
170 << "_ptr p)" << be_nl
172 << "::CORBA::Object_ptr obj = p;" << be_nl
173 << "return ::CORBA::is_nil (obj);" << be_uidt_nl
177 // Generate code for the elements of the interface.
178 if (this->visit_scope (node
) == -1)
180 ACE_ERROR_RETURN ((LM_ERROR
,
181 ACE_TEXT ("be_visitor_interface_cs::")
182 ACE_TEXT ("visit_interface - ")
183 ACE_TEXT ("codegen for scope failed\n")),
187 if (node
->is_local ())
190 << node
->name () << "::" << node
->local_name ()
191 << " (void)" << be_nl
195 if (! node
->is_abstract () && ! node
->is_local ())
198 << node
->name () << "::" << node
->local_name ()
199 << " (void)" << be_nl
;
207 << node
->name () << "::~" << node
->local_name ()
208 << " (void)" << be_nl
;
209 *os
<< "{" << be_nl
<< "}" << be_nl_2
;
211 bool gen_any_destructor
=
212 be_global
->any_support ()
213 && (!node
->is_local ()
214 || be_global
->gen_local_iface_anyops ());
216 if (gen_any_destructor
)
218 *os
<< "void" << be_nl
220 << "::_tao_any_destructor (void *_tao_void_pointer)" << be_nl
222 << node
->local_name () << " *_tao_tmp_pointer =" << be_idt_nl
224 << node
->local_name () << " *> (_tao_void_pointer);" << be_uidt_nl
225 << "::CORBA::release (_tao_tmp_pointer);" << be_uidt_nl
229 if (node
->has_mixed_parentage ())
231 *os
<< "void" << be_nl
232 << node
->name () << "::_add_ref (void)" << be_nl
234 << "this->::CORBA::Object::_add_ref ();"
239 // The _narrow method
240 if (! this->gen_xxx_narrow ("narrow", node
))
242 ACE_ERROR_RETURN ((LM_ERROR
,
243 ACE_TEXT ("be_visitor_interface_cs::")
244 ACE_TEXT ("visit_interface - ")
245 ACE_TEXT ("_narrow () method codegen failed\n")),
249 // The _unchecked_narrow method, not for components.
250 if (c
== 0 && ! this->gen_xxx_narrow ("unchecked_narrow", node
))
252 ACE_ERROR_RETURN ((LM_ERROR
,
253 ACE_TEXT ("be_visitor_interface_cs::")
254 ACE_TEXT ("visit_interface - ")
255 ACE_TEXT ("_unchecked_narrow () method codegen")
256 ACE_TEXT (" failed\n")),
261 *os
<< node
->full_name () << "_ptr" << be_nl
262 << node
->full_name () << "::_nil (void)"
265 << "return 0;" << be_uidt_nl
268 // The _duplicate method
269 *os
<< node
->full_name () << "_ptr" << be_nl
270 << node
->full_name () << "::_duplicate ("
272 << "_ptr obj)" << be_nl
274 << "if (! ::CORBA::is_nil (obj))" << be_idt_nl
276 << "obj->_add_ref ();" << be_uidt_nl
278 << "return obj;" << be_uidt_nl
281 // The _tao_release method
284 *os
<< "void" << be_nl
285 << node
->full_name () << "::_tao_release ("
287 << "_ptr obj)" << be_nl
289 << "::CORBA::release (obj);" << be_uidt_nl
293 *os
<< "::CORBA::Boolean" << be_nl
294 << node
->full_name () << "::_is_a (const char *value)" << be_nl
;
296 *os
<< "{" << be_idt_nl
297 << "if (" << be_idt
<< be_idt_nl
;
299 int status
= node
->gen_is_a_ancestors (os
);
303 ACE_ERROR_RETURN ((LM_ERROR
,
304 ACE_TEXT ("be_visitor_interface_cs::")
305 ACE_TEXT ("visit_interface - ")
306 ACE_TEXT ("gen_is_a_ancestors() failed\n")),
312 << "return true; // success using local knowledge" << be_uidt_nl
314 << "else" << be_idt_nl
317 if (node
->is_abstract () || node
->is_local ())
319 *os
<< "return false;" << be_uidt_nl
;
323 *os
<< "return this->::CORBA::Object::_is_a (value);" << be_uidt_nl
;
326 *os
<< "}" << be_uidt
<< be_uidt_nl
329 *os
<< "const char* " << node
->full_name ()
330 << "::_interface_repository_id (void) const"
333 << "return \"" << node
->repoID ()
334 << "\";" << be_uidt_nl
337 if (be_global
->gen_static_desc_operations ())
339 *os
<< be_nl_2
<< "const char* " << node
->full_name ()
340 << "::_desc_repository_id (void)"
343 << "return \"" << node
->repoID ()
344 << "\";" << be_uidt_nl
347 *os
<< be_nl_2
<< "const char* " << node
->full_name ()
348 << "::_desc_interface_name (void)"
351 << "return \"" << node
->local_name()
352 << "\";" << be_uidt_nl
356 bool const is_loc
= node
->is_local ();
359 << "::CORBA::Boolean" << be_nl
360 << node
->name () << "::marshal (TAO_OutputCDR &"
361 << (is_loc
? " /* " : "") << "cdr"
362 << (is_loc
? " */" : "") << ")" << be_nl
365 << (is_loc
? "false" : "(cdr << this)")
369 if (! node
->is_abstract ())
371 // Smart Proxy classes.
372 if (! node
->is_local () && be_global
->gen_smart_proxies ())
374 be_visitor_context
ctx (*this->ctx_
);
376 ctx
.state (TAO_CodeGen::TAO_INTERFACE_SMART_PROXY_CS
);
377 be_visitor_interface_smart_proxy_cs
isp_visitor (&ctx
);
379 if (node
->accept (&isp_visitor
) == -1)
381 ACE_ERROR_RETURN ((LM_ERROR
,
382 ACE_TEXT ("be_visitor_interface_cs::")
383 ACE_TEXT ("visit_interface - ")
384 ACE_TEXT ("codegen for smart ")
385 ACE_TEXT ("proxy classes failed\n")),
391 if (be_global
->tc_support ())
394 be_visitor_context ctx
= *this->ctx_
;
395 TAO::be_visitor_objref_typecode
tc_visitor (&ctx
);
397 if (node
->accept (&tc_visitor
) == -1)
399 ACE_ERROR_RETURN ((LM_ERROR
,
400 ACE_TEXT ("be_visitor_interface_cs::")
401 ACE_TEXT ("visit_interface - ")
402 ACE_TEXT ("TypeCode definition failed\n")),
411 be_visitor_interface_cs::gen_xxx_narrow (const char *pre
,
414 TAO_OutStream
*os
= this->ctx_
->stream ();
416 *os
<< node
->full_name () << "_ptr" << be_nl
417 << node
->full_name () << "::_" << pre
<< " ("
418 << be_idt
<< be_idt_nl
;
420 if (node
->is_abstract ())
422 *os
<< "::CORBA::AbstractBase_ptr";
426 *os
<< "::CORBA::Object_ptr";
429 *os
<< " _tao_objref)"
434 if (node
->is_local ())
436 *os
<< "return " << node
->local_name ()
437 << "::_duplicate (" << be_idt
<< be_idt_nl
438 << "dynamic_cast<" << node
->local_name ()
439 << "_ptr> (_tao_objref));"
441 << be_uidt
<< be_uidt_nl
446 else if (be_global
->gen_smart_proxies () &&
447 !node
->is_abstract ())
449 *os
<< node
->full_name () << " *proxy = 0;"
451 << "proxy = TAO::Narrow_Utils<"
452 << node
->local_name () << ">::" << pre
<< " (";
454 *os
<< be_idt
<< be_idt_nl
;
456 *os
<< "_tao_objref";
457 if (ACE_OS::strcmp (pre
, "narrow") == 0)
460 << "\"" << node
->repoID () << "\"";
465 *os
<< be_uidt
<< be_uidt
<< be_nl
466 << "return TAO_" << node
->flat_name ()
467 << "_PROXY_FACTORY_ADAPTER::instance ()->create_proxy (proxy);"
468 << be_uidt
<< be_uidt_nl
473 *os
<< "return" << be_idt_nl
;
475 if (!node
->is_abstract ())
477 *os
<< "TAO::Narrow_Utils<"
478 << node
->local_name () << ">::" << pre
<< " (";
482 *os
<< "TAO::AbstractBase_Narrow_Utils<"
483 << node
->local_name () << ">::" << pre
<<" (";
486 *os
<< be_idt
<< be_idt_nl
489 if (ACE_OS::strcmp (pre
, "narrow") == 0)
492 << "\"" << node
->repoID () << "\"";
497 *os
<< be_uidt
<< be_uidt
<< be_uidt
<< be_uidt_nl
505 be_visitor_interface_cs::visit_component (be_component
*node
)
507 return this->visit_interface (node
);
511 be_visitor_interface_cs::visit_connector (be_connector
*node
)
513 return this->visit_interface (node
);
517 be_visitor_interface_cs::visit_extended_port (be_extended_port
*node
)
519 this->ctx_
->port_prefix () = node
->local_name ()->get_string ();
520 this->ctx_
->port_prefix () += '_';
522 /// If the port visit traverses any attributes defined in the
523 /// original porttype, this is a way for visitors down the
524 /// line to tell what scope we are actually in.
525 this->ctx_
->interface (
526 dynamic_cast<be_interface
*> (node
->defined_in ()));
528 /// Will ignore everything but porttype attributes.
529 int status
= this->visit_scope (node
->port_type ());
533 ACE_ERROR_RETURN ((LM_ERROR
,
534 ACE_TEXT ("be_visitor_interface_ch")
535 ACE_TEXT ("::visit_extended_port - ")
536 ACE_TEXT ("visit_scope failed\n")),
540 /// Reset port prefix string.
541 this->ctx_
->port_prefix () = "";
546 be_visitor_interface_cs::visit_mirror_port (be_mirror_port
*node
)
548 this->ctx_
->port_prefix () = node
->local_name ()->get_string ();
549 this->ctx_
->port_prefix () += '_';
551 /// If the port visit traverses any attributes defined in the
552 /// original porttype, this is a way for visitors down the
553 /// line to tell what scope we are actually in.
554 this->ctx_
->interface (
555 dynamic_cast<be_interface
*> (node
->defined_in ()));
557 /// Will ignore everything but porttype attributes.
558 int status
= this->visit_scope (node
->port_type ());
562 ACE_ERROR_RETURN ((LM_ERROR
,
563 ACE_TEXT ("be_visitor_interface_ch")
564 ACE_TEXT ("::visit_mirror_port - ")
565 ACE_TEXT ("visit_scope failed\n")),
569 /// Reset port prefix string.
570 this->ctx_
->port_prefix () = "";
575 be_visitor_interface_cs::gen_abstract_ops_helper (be_interface
*node
,
579 // If the derived interface is local, the abstract parent's operation
580 // was generated as pure virtual.
581 if (!base
->is_abstract () || node
->is_local ())
587 be_visitor_context ctx
;
590 for (UTL_ScopeActiveIterator
si (base
, UTL_Scope::IK_decls
);
598 ACE_ERROR_RETURN ((LM_ERROR
,
599 "(%N:%l) be_visitor_interface_cs::"
600 "gen_abstract_ops_helper - "
601 "bad node in this scope\n"),
605 if (d
->node_type () == AST_Decl::NT_op
)
607 UTL_ScopedName
*item_new_name
= 0;
608 ACE_NEW_RETURN (item_new_name
,
609 UTL_ScopedName (d
->local_name ()->copy (),
613 UTL_ScopedName
*new_op_name
=
614 (UTL_ScopedName
*)node
->name ()->copy ();
615 new_op_name
->nconc (item_new_name
);
617 be_operation
*op
= dynamic_cast<be_operation
*> (d
);
618 UTL_ScopedName
*old_op_name
=
619 (UTL_ScopedName
*) op
->name ()->copy ();
620 op
->set_name (new_op_name
);
621 op
->set_defined_in (node
);
622 op
->is_abstract (node
->is_abstract ());
624 ctx
.state (TAO_CodeGen::TAO_OPERATION_CS
);
625 be_visitor_operation_cs
op_visitor (&ctx
);
626 op_visitor
.visit_operation (op
);
628 op
->set_name (old_op_name
);
629 op
->set_defined_in (base
);
630 op
->is_abstract (base
->is_abstract ());