2 //=============================================================================
4 * @file operation_ss.cpp
6 * Visitor generating code for Operation in the server skeleton
8 * @author Aniruddha Gokhale
10 //=============================================================================
12 #include "operation.h"
14 be_visitor_operation_ss::be_visitor_operation_ss (be_visitor_context
*ctx
)
15 : be_visitor_operation (ctx
)
19 be_visitor_operation_ss::~be_visitor_operation_ss ()
24 be_visitor_operation_ss::visit_operation (be_operation
* node
)
26 /// No server-side code generation for these implied IDL nodes.
27 if (node
->is_sendc_ami ())
32 TAO_OutStream
*os
= this->ctx_
->stream ();
33 be_type
*bt
= nullptr;
35 this->ctx_
->node (node
);
39 // If there is an argument of type "native", return immediately.
40 if (node
->has_native ())
45 // Retrieve the operation return type.
46 bt
= dynamic_cast<be_type
*> (node
->return_type ());
50 ACE_ERROR_RETURN ((LM_ERROR
,
51 ACE_TEXT ("be_visitor_operation_ss::")
52 ACE_TEXT ("visit_operation - ")
53 ACE_TEXT ("Bad return type\n")),
57 return this->gen_skel_operation_body (node
, bt
);
61 be_visitor_operation_ss::visit_argument (be_argument
*node
)
63 // This method is used to generate the ParamData table entry.
65 TAO_OutStream
*os
= this->ctx_
->stream ();
67 // Retrieve the type for this argument.
68 be_type
*bt
= dynamic_cast<be_type
*> (node
->field_type ());
72 ACE_ERROR_RETURN ((LM_ERROR
,
73 "(%N:%l) be_visitor_operation_ss::"
75 "Bad argument type\n"),
80 *os
<< "{" << bt
->tc_name () << ", ";
81 switch (node
->direction ())
83 case AST_Argument::dir_IN
:
84 *os
<< "::CORBA::ARG_IN, ";
86 case AST_Argument::dir_INOUT
:
87 *os
<< "::CORBA::ARG_INOUT, ";
89 case AST_Argument::dir_OUT
:
90 *os
<< "::CORBA::ARG_OUT, ";
99 be_visitor_operation_ss::gen_pre_skel_info (be_operation
* node
)
101 be_visitor_context ctx
= *this->ctx_
;
102 be_visitor_operation_exceptlist_ss
visitor (&ctx
);
104 if (node
->accept (&visitor
) == -1)
106 ACE_ERROR_RETURN ((LM_ERROR
,
108 "be_visitor_operation_ss::"
109 "gen_pre_skel_info - "
110 "Exception TypeCode list generation error\n"),
118 be_visitor_operation_ss::gen_skel_operation_body (be_operation
* node
,
119 be_type
* return_type
)
121 TAO_OutStream
* const os
= this->ctx_
->stream ();
123 // We need the interface node in which this operation was
124 // defined. However, if this operation node was an attribute node
125 // in disguise, we get this information from the context.
126 UTL_Scope
*s
= this->ctx_
->attribute ()
127 ? this->ctx_
->attribute ()->defined_in ()
128 : node
->defined_in ();
130 be_interface
*intf
= dynamic_cast<be_interface
*> (s
);
134 ACE_ERROR_RETURN ((LM_ERROR
,
135 ACE_TEXT ("be_visitor_operation_ss::")
136 ACE_TEXT ("visit_operation - ")
137 ACE_TEXT ("bad interface scope\n")),
141 ACE_CString upcall_command_name
=
142 this->ctx_
->port_prefix ()
143 + ACE_CString (node
->local_name ()->get_string ()) + "_"
144 + ACE_CString (intf
->local_name ());
146 // Check if we are an attribute node in disguise.
147 if (this->ctx_
->attribute ())
149 // Now check if we are a "get" or "set" operation.
150 if (node
->nmembers () == 1)
152 upcall_command_name
= "_set_" + upcall_command_name
;
156 upcall_command_name
= "_get_" + upcall_command_name
;
160 // Generate the local class encapsulating the actual servant upcall
161 // command/invocation.
162 be_visitor_operation_upcall_command_ss
upcall_command_visitor (this->ctx_
);
163 upcall_command_visitor
.visit (node
,
164 intf
->full_skel_name (),
165 upcall_command_name
.c_str ());
167 TAO_INSERT_COMMENT (os
);
169 *os
<< "void " << intf
->full_skel_name () << "::";
171 // Check if we are an attribute node in disguise.
172 if (this->ctx_
->attribute ())
174 // Now check if we are a "get" or "set" operation.
175 if (node
->nmembers () == 1)
185 *os
<< this->ctx_
->port_prefix ().c_str () << node
->local_name ()
186 << "_skel (" << be_idt_nl
187 << "TAO_ServerRequest & server_request," << be_nl
188 << "TAO::Portable_Server::Servant_Upcall *TAO_INTERCEPTOR (servant_upcall)," << be_nl
189 << "TAO_ServantBase *servant)" << be_uidt_nl
;
191 // Generate the actual code for the skeleton. However, if any of the
192 // argument types is "native", we do not generate any skeleton
193 // last argument - is always CORBA::Environment.
194 *os
<< "{" << be_idt
;
196 // Generate all the tables and other pre-skel info.
197 if (this->gen_pre_skel_info (node
) == -1)
199 ACE_ERROR_RETURN ((LM_ERROR
,
200 "(%N:%l) be_visitor_operation_ss::"
202 "gen_pre_skel_info failed\n"),
206 // Declare return type helper class.
208 *os
<< "TAO::SArg_Traits< ";
210 this->gen_arg_template_param_name (node
,
214 *os
<< ">::ret_val retval;";
216 // Declare the argument helper classes.
217 this->gen_skel_body_arglist (node
, os
);
220 << "TAO::Argument * const args[] =" << be_idt_nl
222 << "std::addressof(retval)";
224 for (UTL_ScopeActiveIterator
arg_list_iter (node
, UTL_Scope::IK_decls
);
225 ! arg_list_iter
.is_done ();
226 arg_list_iter
.next ())
228 AST_Argument
* const arg
=
229 dynamic_cast<AST_Argument
*> (arg_list_iter
.item ());
232 << "std::addressof(_tao_" << arg
->local_name () << ")";
236 << "};" << be_uidt_nl
<< be_nl
;
238 // Get the right object implementation.
239 *os
<< intf
->full_skel_name () << " * const impl =" << be_idt_nl
241 << intf
->full_skel_name () << " *> (servant);" << be_uidt
<< be_nl_2
;
243 *os
<< "if (!impl)" << be_idt_nl
245 << "throw ::CORBA::INTERNAL ();" << be_uidt_nl
246 << "}" << be_uidt
<< be_nl_2
;
248 // Upcall_Command instantiation.
249 *os
<< upcall_command_name
.c_str()
250 << " command (" << be_idt_nl
253 if (!node
->void_return_type () || node
->argument_count () > 0)
255 // server_request.operation_details () will be non-zero in the
256 // thru-POA collocation case. Use them if available.
259 if (be_global
->gen_thru_poa_collocation ())
260 *os
<< "server_request.operation_details ()," << be_nl
;
265 *os
<< ");" << be_uidt_nl
<< be_nl
;
267 *os
<< "TAO::Upcall_Wrapper upcall_wrapper;" << be_nl
268 << "upcall_wrapper.upcall (server_request" << be_nl
269 << " , args" << be_nl
270 << " , " << (node
->argument_count () + 1) << be_nl
272 << "\n#if TAO_HAS_INTERCEPTORS == 1" << be_nl
273 << " , servant_upcall" << be_nl
;
275 if (node
->exceptions () && be_global
->tc_support ())
277 *os
<< " , exceptions" << be_nl
278 << " , " << node
->exceptions ()->length ();
282 *os
<< " , nullptr" << be_nl
286 *os
<< "\n#endif /* TAO_HAS_INTERCEPTORS == 1 */" << be_nl
287 << " );" << be_uidt_nl
294 be_visitor_operation_ss::gen_skel_body_arglist (be_operation
* node
,
297 for (UTL_ScopeActiveIterator
arg_decl_iter (node
, UTL_Scope::IK_decls
);
298 ! arg_decl_iter
.is_done ();
299 arg_decl_iter
.next ())
301 AST_Argument
* const arg
=
302 dynamic_cast<AST_Argument
*> (arg_decl_iter
.item ());
305 << "TAO::SArg_Traits< ";
307 this->gen_arg_template_param_name (arg
,
313 switch (arg
->direction ())
315 case AST_Argument::dir_IN
:
318 case AST_Argument::dir_INOUT
:
321 case AST_Argument::dir_OUT
:
327 *os
<< "_arg_val _tao_" << arg
->local_name () << ";";