2 //=============================================================================
6 * Visitor generating code for Operation in the stubs file.
8 * @author Aniruddha Gokhale
9 * @author Alexander Babu Arulanthu <alex@cs.wustl.edu> Michael Kircher
11 //=============================================================================
13 #include "operation.h"
15 be_visitor_operation_ami_cs::be_visitor_operation_ami_cs (
16 be_visitor_context
*ctx
)
17 : be_visitor_operation (ctx
)
21 be_visitor_operation_ami_cs::~be_visitor_operation_ami_cs ()
25 // Processing to be done after every element in the scope is
28 be_visitor_operation_ami_cs::post_process (be_decl
*bd
)
30 // all we do here is to insert a comma and a newline
31 TAO_OutStream
*os
= this->ctx_
->stream ();
33 if (!this->last_node (bd
))
42 be_visitor_operation_ami_cs::visit_operation (be_operation
*node
)
44 // No sendc method for oneway operations.
45 if (node
->flags () == AST_Operation::OP_oneway
)
50 be_visitor_context ctx
;
51 TAO_OutStream
*os
= this->ctx_
->stream ();
52 this->ctx_
->node (node
);
54 TAO_INSERT_COMMENT (os
);
56 // Generate the return type mapping. Return type is simply void.
60 // Generate the operation name.
62 // Grab the scope name.
64 dynamic_cast<be_scope
*> (node
->defined_in ())->decl ();
66 if (parent
== nullptr)
68 ACE_ERROR_RETURN ((LM_ERROR
,
69 "(%N:%l) be_visitor_operation_ami_cs::"
71 "scope name is nil\n"),
75 // Generate the scope::operation name.
76 *os
<< parent
->full_name ()
77 << "::" << this->ctx_
->port_prefix ().c_str ()
78 << node
->local_name ()->get_string ();
80 // Generate the argument list with the appropriate mapping (same as
81 // in the header file)
83 be_visitor_operation_arglist
oa_visitor (&ctx
);
85 // Get the AMI version from the strategy class.
86 be_operation
*ami_op
= node
;
88 if (ami_op
->accept (&oa_visitor
) == -1)
90 ACE_ERROR_RETURN ((LM_ERROR
,
91 "(%N:%l) be_visitor_operation_ami_cs::"
93 "codegen for argument list failed\n"),
97 // Generate the actual code for the stub. However, if any of the argument
98 // types is "native", we flag a MARSHAL exception.
100 *os
<< be_nl
<< "{" << be_idt
;
102 if (node
->has_native ()) // native exists => no stub
104 be_predefined_type
bpt (AST_PredefinedType::PT_void
,
107 int const status
= this->gen_raise_exception ("::CORBA::MARSHAL",
112 ACE_ERROR_RETURN ((LM_ERROR
,
113 "(%N:%l) be_visitor_operation_ami_cs::"
115 "codegen for has-native exception failed\n"),
122 << "if (!this->is_evaluated ())" << be_idt_nl
124 << "::CORBA::Object::tao_object_initialize (this);"
126 << "}" << be_uidt_nl
<< be_nl
;
129 // Includes the reply handler, but we have to add 1 for the retval anyway.
130 int nargs
= ami_op
->argument_count ();
134 // No arguments other than the reply handler, and the return
135 // type is void. No need to generate argument list.
138 << "TAO::Argument ** _the_tao_operation_signature {};";
139 nargs
= 0; // Don't count the reply handler.
144 << "TAO::Arg_Traits<void>::"
145 << (node
->flags () == AST_Operation::OP_oneway
&&
146 be_global
->use_clonable_in_args() ? "clonable_" : "")
147 << "ret_val _tao_retval;";
149 // Declare the argument helper classes.
150 this->gen_stub_body_arglist (ami_op
, os
, true);
152 // Assemble the arg helper class pointer array.
154 << "TAO::Argument *_the_tao_operation_signature[] =" << be_idt_nl
156 << "std::addressof(_tao_retval)";
158 AST_Argument
*arg
= nullptr;
159 UTL_ScopeActiveIterator
arg_list_iter (ami_op
,
160 UTL_Scope::IK_decls
);
162 // For a sendc_* operation, skip the reply handler (first argument).
163 arg_list_iter
.next ();
165 for (; ! arg_list_iter
.is_done (); arg_list_iter
.next ())
167 arg
= dynamic_cast<AST_Argument
*> (arg_list_iter
.item ());
170 << "std::addressof(_tao_" << arg
->local_name () << ")";
177 ACE_CString
base (node
->local_name ()->get_string ());
179 /// The sendc_* operation makes the invocation with the
180 /// original operation name.
181 ACE_CString
lname_str (base
.substr (ACE_OS::strlen ("sendc_")));
182 const char *lname
= lname_str
.c_str ();
184 ACE_CString
opname (node
->is_attr_op () ? "_" : "");
187 /// Some compilers can't resolve the stream operator overload.
188 const char *op_name
= opname
.c_str ();
189 ACE_CString::size_type len
= opname
.length ();
192 << "TAO::Asynch_Invocation_Adapter _invocation_call (" << be_idt
<< be_idt_nl
194 << "_the_tao_operation_signature," << be_nl
195 << nargs
<< "," << be_nl
196 << "\"" << op_name
<< "\"," << be_nl
197 << len
<< "," << be_nl
;
199 *os
<< "TAO::TAO_CO_NONE";
200 if (be_global
->gen_direct_collocation())
202 *os
<< " | TAO::TAO_CO_DIRECT_STRATEGY";
204 if (be_global
->gen_thru_poa_collocation())
206 *os
<< " | TAO::TAO_CO_THRU_POA_STRATEGY";
209 if (!node
->has_in_arguments ())
212 << "TAO::TAO_ASYNCHRONOUS_CALLBACK_INVOCATION," << be_nl
220 << "_invocation_call.invoke (" << be_idt
<< be_idt_nl
221 << "ami_handler," << be_nl
224 if (parent
->is_nested ())
227 dynamic_cast<be_scope
*> (parent
->defined_in ())->decl ();
229 *os
<< gparent
->name () << "::";
232 *os
<< "AMI_" << parent
->local_name () << "Handler::"
233 << lname
<< "_reply_stub" << be_uidt_nl
242 // This method is used to generate the ParamData table entry.
244 be_visitor_operation_ami_cs::visit_argument (be_argument
*node
)
246 TAO_OutStream
*os
= this->ctx_
->stream ();
247 be_type
*bt
= nullptr; // argument type
249 // Retrieve the type for this argument.
250 bt
= dynamic_cast<be_type
*> (node
->field_type ());
254 ACE_ERROR_RETURN ((LM_ERROR
,
255 "(%N:%l) be_visitor_operation_ami_cs::"
257 "Bad argument type\n"),
262 *os
<< "{" << bt
->tc_name () << ", ";
264 switch (node
->direction ())
266 case AST_Argument::dir_IN
:
269 case AST_Argument::dir_INOUT
:
270 *os
<< "PARAM_INOUT, ";
272 case AST_Argument::dir_OUT
:
273 *os
<< "PARAM_OUT, ";
283 be_visitor_operation_ami_cs::gen_pre_stub_info (be_operation
*,
286 // Nothing to be done here, we do not throw any exceptions
287 // besides system exceptions, so we do not need an user exception table.