2 //=============================================================================
4 * @file interface_ch.cpp
6 * Visitor generating code for Interfaces in the client header
8 * @author Aniruddha Gokhale
10 //=============================================================================
12 #include "interface.h"
14 be_visitor_interface_ch::be_visitor_interface_ch (be_visitor_context
*ctx
)
15 : be_visitor_interface (ctx
)
19 be_visitor_interface_ch::~be_visitor_interface_ch ()
24 be_visitor_interface_ch::visit_interface (be_interface
*node
)
26 if (node
->cli_hdr_gen () || node
->imported ())
31 // This will be a no-op if it has already been done by a forward
33 node
->gen_var_out_seq_decls ();
35 TAO_OutStream
*os
= this->ctx_
->stream ();
39 TAO_INSERT_COMMENT (os
);
41 AST_Component
*c
= dynamic_cast<AST_Component
*> (node
);
43 // Now generate the class definition.
45 << "class " << be_global
->stub_export_macro ()
46 << " " << node
->local_name () << be_idt_nl
49 node
->gen_stub_inheritance (os
);
55 << "public:" << be_idt
;
57 if (!node
->is_local ())
59 bool abs
= node
->is_abstract ();
62 << "friend class TAO::"
63 << (abs
? "AbstractBase_" : "") << "Narrow_Utils<"
64 << node
->local_name () << ">;";
67 node
->gen_stub_decls (os
);
69 // Generate the static _duplicate, _narrow, _unchecked_narrow and
72 << "// The static operations." << be_nl
73 << "static " << node
->local_name () << "_ptr " << "_duplicate ("
74 << node
->local_name () << "_ptr obj);" << be_nl_2
;
78 *os
<< "static void _tao_release ("
79 << node
->local_name () << "_ptr obj);"
83 if (! this->gen_xxx_narrow ("_narrow", node
, os
))
85 ACE_ERROR_RETURN ((LM_ERROR
,
86 ACE_TEXT ("Error in ")
87 ACE_TEXT ("be_visitor_interface_ch::")
88 ACE_TEXT ("visit_interface while generating ")
89 ACE_TEXT ("_narrow () declaration\n")),
95 if (! this->gen_xxx_narrow ("_unchecked_narrow", node
, os
))
97 ACE_ERROR_RETURN ((LM_ERROR
,
98 ACE_TEXT ("Error in ")
99 ACE_TEXT ("be_visitor_interface_ch::")
100 ACE_TEXT ("visit_interface while generating ")
101 ACE_TEXT ("_unchecked_narrow () declaration\n")),
106 *os
<< "static " << node
->local_name () << "_ptr _nil ();";
108 // Generate code for the interface definition by traversing thru the
109 // elements of its scope. We depend on the front-end to have made sure
110 // that only legal syntactic elements appear in our scope.
112 if (this->visit_scope (node
) == -1)
114 ACE_ERROR_RETURN ((LM_ERROR
,
115 ACE_TEXT ("be_visitor_interface_ch::")
116 ACE_TEXT ("visit_interface - ")
117 ACE_TEXT ("codegen for scope failed\n")),
121 if (node
->is_local ())
123 if (node
->convert_parent_ops (this) == -1)
125 ACE_ERROR_RETURN ((LM_ERROR
,
126 ACE_TEXT ("be_visitor_interface_ch::")
127 ACE_TEXT ("visit_interface - ")
128 ACE_TEXT ("converting parent ops failed\n")),
135 TAO_INSERT_COMMENT (os
);
139 // If we inherit from both CORBA::Object and CORBA::AbstractBase,
140 // we have to override _add_ref() to avoid ambiguity.
141 if (node
->has_mixed_parentage ())
143 *os
<< "virtual void _add_ref ();" << be_nl_2
;
147 *os
<< "virtual ::CORBA::Boolean _is_a (const char *type_id);"
150 // The _interface_repository_id method.
151 *os
<< "virtual const char* _interface_repository_id "
154 if (be_global
->gen_static_desc_operations ())
156 *os
<< be_nl
<< "static const char* _desc_repository_id ();";
158 *os
<< be_nl
<< "static const char* _desc_interface_name ();";
161 // The virtual marshal method, to prevent marshal of local interfaces.
163 << "virtual ::CORBA::Boolean marshal "
164 << "(TAO_OutputCDR &cdr);";
166 // If we are generating CORBA Policy we need to add some more methods
167 if (ACE_OS::strcmp (node
->full_name (), "CORBA::Policy") == 0)
170 << "virtual CORBA::Boolean _tao_encode (TAO_OutputCDR &);" << be_nl
171 << "virtual CORBA::Boolean _tao_decode (TAO_InputCDR &);" << be_nl
172 << "virtual TAO_Cached_Policy_Type _tao_cached_type () const;" << be_nl
173 << "virtual TAO_Policy_Scope _tao_scope () const;" << be_nl
;
176 if (be_global
->gen_ostream_operators ())
179 << "virtual std::ostream &_tao_stream_v (std::ostream &) const;";
182 *os
<< be_uidt_nl
<< be_nl
183 << "protected:" << be_idt_nl
;
185 if (! node
->is_local ())
187 // Generate the "protected" constructor so that users cannot
189 if (! node
->is_abstract ())
191 *os
<< "// Concrete interface only." << be_nl
192 << node
->local_name () << " ();"
197 if (node
->is_abstract () || node
->is_local ())
199 // Protected default constructor for abstract interfaces.
200 *os
<< "// Abstract or local interface only." << be_nl
201 << node
->local_name () << " ();" << be_nl_2
;
204 if (node
->is_abstract ())
206 // Protected copy constructor for abstract interfaces.
207 *os
<< "// Protected for abstract interfaces." << be_nl
208 << node
->local_name () << " (const "
209 << node
->local_name () << " &);" << be_nl_2
;
212 // Local interfaces don't support stub objects.
213 if (! node
->is_local ())
215 if (! node
->is_abstract ())
217 *os
<< "// Concrete non-local interface only." << be_nl
218 << node
->local_name () << " ("
219 << "::IOP::IOR *ior, "
220 << "TAO_ORB_Core *orb_core);"
224 *os
<< "// Non-local interface only." << be_nl
225 << node
->local_name () << " (" << be_idt
<< be_idt_nl
226 << "TAO_Stub *objref," << be_nl
227 << "::CORBA::Boolean _tao_collocated = false," << be_nl
228 << "TAO_Abstract_ServantBase *servant = nullptr," << be_nl
229 << "TAO_ORB_Core *orb_core = nullptr);"
230 << be_uidt
<< be_uidt
;
235 // Friends declarations, component only.
237 << "friend class " << node
->direct_proxy_impl_name ()
241 // Protected destructor.
243 << "virtual ~" << node
->local_name () << " () = default;";
245 // Private copy constructor and assignment operator. These are not
246 // allowed, hence they are private.
247 *os
<< be_uidt_nl
<< be_nl
248 << "private:" << be_idt_nl
;
250 // Abstract interfaces have a *protected* copy constructor.
251 if (! node
->is_abstract ())
253 *os
<< "// Private and unimplemented for concrete interfaces." << be_nl
254 << node
->local_name () << " (const "
255 << node
->local_name () << " &) = delete;" << be_nl
256 << node
->local_name () << " ("
257 << node
->local_name () << " &&) = delete;" << be_nl
;
260 *os
<< node
->local_name ()
261 << " &operator= (const " << node
->local_name () << " &) = delete;" << be_nl
262 << node
->local_name ()
263 << " &operator= (" << node
->local_name () << " &&) = delete;" << be_uidt_nl
266 be_visitor_context
ctx (*this->ctx_
);
268 // Don't support smart proxies for local interfaces.
269 if (! node
->is_local ())
271 if (be_global
->gen_smart_proxies ())
275 // Smart Proxy related classes.
276 ctx
.state (TAO_CodeGen::TAO_INTERFACE_SMART_PROXY_CH
);
277 be_visitor_interface_smart_proxy_ch
sp_visitor (&ctx
);
279 if (node
->accept (&sp_visitor
) == -1)
281 ACE_ERROR_RETURN ((LM_ERROR
,
282 ACE_TEXT ("be_visitor_interface_ch::")
283 ACE_TEXT ("visit_interface - ")
284 ACE_TEXT ("codegen for smart ")
285 ACE_TEXT ("proxy classes failed\n")),
291 if (be_global
->tc_support ())
293 be_visitor_typecode_decl
td_visitor (&ctx
);
295 if (node
->accept (&td_visitor
) == -1)
297 ACE_ERROR_RETURN ((LM_ERROR
,
298 ACE_TEXT ("be_visitor_interface_ch::")
299 ACE_TEXT ("visit_interface - ")
300 ACE_TEXT ("TypeCode declaration failed\n")),
305 node
->cli_hdr_gen (true);
310 be_visitor_interface_ch::visit_component (be_component
*node
)
312 return this->visit_interface (node
);
316 be_visitor_interface_ch::visit_connector (be_connector
*node
)
318 return this->visit_interface (node
);
322 be_visitor_interface_ch::visit_extended_port (be_extended_port
*node
)
324 this->ctx_
->port_prefix () = node
->local_name ()->get_string ();
325 this->ctx_
->port_prefix () += '_';
327 /// If the port visit traverses any attributes defined in the
328 /// original porttype, this is a way for visitors down the
329 /// line to tell what scope we are actually in.
330 this->ctx_
->interface (
331 dynamic_cast<be_interface
*> (node
->defined_in ()));
333 /// Will ignore everything but porttype attributes.
334 int status
= this->visit_scope (node
->port_type ());
338 ACE_ERROR_RETURN ((LM_ERROR
,
339 ACE_TEXT ("be_visitor_interface_ch")
340 ACE_TEXT ("::visit_extended_port - ")
341 ACE_TEXT ("visit_scope failed\n")),
345 /// Reset port prefix string.
346 this->ctx_
->port_prefix () = "";
351 be_visitor_interface_ch::visit_mirror_port (be_mirror_port
*node
)
353 this->ctx_
->port_prefix () = node
->local_name ()->get_string ();
354 this->ctx_
->port_prefix () += '_';
356 /// If the port visit traverses any attributes defined in the
357 /// original porttype, this is a way for visitors down the
358 /// line to tell what scope we are actually in.
359 this->ctx_
->interface (
360 dynamic_cast<be_interface
*> (node
->defined_in ()));
362 /// Will ignore everything but porttype attributes.
363 int status
= this->visit_scope (node
->port_type ());
367 ACE_ERROR_RETURN ((LM_ERROR
,
368 ACE_TEXT ("be_visitor_interface_ch")
369 ACE_TEXT ("::visit_mirror_port - ")
370 ACE_TEXT ("visit_scope failed\n")),
374 /// Reset port prefix string.
375 this->ctx_
->port_prefix () = "";
380 be_visitor_interface_ch::gen_abstract_ops_helper (be_interface
*node
,
384 if (!base
->is_abstract ())
389 AST_Decl
*d
= nullptr;
390 be_visitor_context ctx
;
393 for (UTL_ScopeActiveIterator
si (base
, UTL_Scope::IK_decls
);
401 ACE_ERROR_RETURN ((LM_ERROR
,
402 ACE_TEXT ("be_interface::")
403 ACE_TEXT ("gen_abstract_ops_helper - ")
404 ACE_TEXT ("bad node in this scope\n")),
408 if (d
->node_type () == AST_Decl::NT_op
)
410 be_operation
*op
= dynamic_cast<be_operation
*> (d
);
411 op
->set_local (node
->is_local ());
412 ctx
.state (TAO_CodeGen::TAO_OPERATION_CH
);
413 be_visitor_operation_ch
op_visitor (&ctx
);
414 op_visitor
.visit_operation (op
);
415 op
->set_local (base
->is_local ());
423 be_visitor_interface_ch::gen_xxx_narrow (const char *nar
,
427 *os
<< "static " << node
->local_name () << "_ptr "
430 if (node
->is_abstract ())
432 *os
<< "::CORBA::AbstractBase_ptr obj";
436 *os
<< "::CORBA::Object_ptr obj";
439 *os
<< ");" << be_nl
;