Revert "Use a variable on the stack to not have a temporary in the call"
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_operation / ami_cs.cpp
blob7c59fada12b5569b10f83547676a6cb22c725ed4
2 //=============================================================================
3 /**
4 * @file ami_cs.cpp
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
26 // processed.
27 int
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))
35 *os << ",\n";
38 return 0;
41 int
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)
47 return 0;
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.
57 *os << be_nl_2
58 << "void" << be_nl;
60 // Generate the operation name.
62 // Grab the scope name.
63 be_decl *parent =
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::"
70 "visit_operation - "
71 "scope name is nil\n"),
72 -1);
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)
82 ctx = *this->ctx_;
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::"
92 "visit_operation - "
93 "codegen for argument list failed\n"),
94 -1);
97 // Generate the actual code for the stub. However, if any of the argument
98 // types is "native", we flag a MARSHAL exception.
99 // last argument
100 *os << be_nl << "{" << be_idt;
102 if (node->has_native ()) // native exists => no stub
104 be_predefined_type bpt (AST_PredefinedType::PT_void,
105 nullptr);
107 int const status = this->gen_raise_exception ("::CORBA::MARSHAL",
108 "");
110 if (status == -1)
112 ACE_ERROR_RETURN ((LM_ERROR,
113 "(%N:%l) be_visitor_operation_ami_cs::"
114 "visit_operation - "
115 "codegen for has-native exception failed\n"),
116 -1);
119 else
121 *os << be_nl
122 << "if (!this->is_evaluated ())" << be_idt_nl
123 << "{" << be_idt_nl
124 << "::CORBA::Object::tao_object_initialize (this);"
125 << be_uidt_nl
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 ();
132 if (nargs == 1)
134 // No arguments other than the reply handler, and the return
135 // type is void. No need to generate argument list.
137 *os << be_nl_2
138 << "TAO::Argument ** _the_tao_operation_signature {};";
139 nargs = 0; // Don't count the reply handler.
141 else
143 *os << be_nl<< be_nl
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.
153 *os << be_nl_2
154 << "TAO::Argument *_the_tao_operation_signature[] =" << be_idt_nl
155 << "{" << 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 ());
169 *os << "," << be_nl
170 << "std::addressof(_tao_" << arg->local_name () << ")";
173 *os << be_uidt_nl
174 << "};" << be_uidt;
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 () ? "_" : "");
185 opname += lname;
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 ();
191 *os << be_nl_2
192 << "TAO::Asynch_Invocation_Adapter _invocation_call (" << be_idt << be_idt_nl
193 << "this," << be_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 ())
211 *os << "," << be_nl
212 << "TAO::TAO_ASYNCHRONOUS_CALLBACK_INVOCATION," << be_nl
213 << "false";
216 *os << be_uidt_nl
217 << ");" << be_uidt;
219 *os << be_nl_2
220 << "_invocation_call.invoke (" << be_idt << be_idt_nl
221 << "ami_handler," << be_nl
222 << "&";
224 if (parent->is_nested ())
226 be_decl *gparent =
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
234 << ");" << be_uidt;
236 *os << be_uidt_nl
237 << "}";
239 return 0;
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 ());
252 if (!bt)
254 ACE_ERROR_RETURN ((LM_ERROR,
255 "(%N:%l) be_visitor_operation_ami_cs::"
256 "visit_argument - "
257 "Bad argument type\n"),
258 -1);
261 os->indent ();
262 *os << "{" << bt->tc_name () << ", ";
264 switch (node->direction ())
266 case AST_Argument::dir_IN:
267 *os << "PARAM_IN, ";
268 break;
269 case AST_Argument::dir_INOUT:
270 *os << "PARAM_INOUT, ";
271 break;
272 case AST_Argument::dir_OUT:
273 *os << "PARAM_OUT, ";
274 break;
277 *os << "0}";
279 return 0;
283 be_visitor_operation_ami_cs::gen_pre_stub_info (be_operation *,
284 be_type *)
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.
288 return 0;