Use =default for skeleton copy constructor
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_interface / amh_sh.cpp
blob4dd5df87a48a92da388fe53834b0474b6969034a
1 //=============================================================================
2 /**
3 * @file amh_sh.cpp
5 * Specialized interface visitor for AMH generates code that is
6 * specific to AMH interfaces.
8 * @author Darrell Brunsch <brunsch@cs.wustl.edu>
9 */
10 //=============================================================================
12 #include "interface.h"
14 be_visitor_amh_interface_sh::be_visitor_amh_interface_sh (
15 be_visitor_context *ctx)
16 : be_visitor_interface_sh (ctx)
20 be_visitor_amh_interface_sh::~be_visitor_amh_interface_sh ()
24 // The node is the original interface node but we 'tweak' with the
25 // local_name and the the operation signatures to generate the AMH
26 // skeleton on the 'fly'.
28 int
29 be_visitor_amh_interface_sh::visit_interface (be_interface *node)
31 if (node->srv_hdr_gen () || node->imported () || node->is_local ())
33 return 0;
36 // Do not generate AMH classes for any sort of implied IDL.
37 if (node->original_interface () != nullptr)
39 return 0;
42 TAO_OutStream *os = this->ctx_->stream ();
43 ACE_CString class_name;
45 TAO_INSERT_COMMENT (os);
47 // We shall have a POA_ prefix only if we are at the topmost level.
48 if (!node->is_nested ())
50 // We are outermost.
51 class_name += "POA_AMH_";
52 class_name += node->local_name ();
54 else
56 class_name += "AMH_";
57 class_name += node->local_name ();
60 // Generate the skeleton class name.
61 *os << "class " << class_name.c_str () << ";" << be_nl;
63 // Generate the _ptr declaration.
64 *os << "typedef " << class_name.c_str () << " *" << class_name.c_str ()
65 << "_ptr;" << be_nl_2;
67 // Now generate the class definition.
68 *os << "class " << be_global->skel_export_macro ()
69 << " " << class_name.c_str () << be_idt_nl << ": " << be_idt;
71 long n_parents = node->n_inherits ();
73 if (n_parents > 0)
75 for (int i = 0; i < n_parents; ++i)
77 ACE_CString amh_name ("POA_");
79 // @@ The following code is *NOT* exception-safe.
80 char *buf = nullptr;
81 be_interface *base =
82 dynamic_cast<be_interface*> (node->inherits ()[i]);
83 base->compute_full_name ("AMH_", "", buf);
84 amh_name += buf;
85 // buf was allocated by ACE_OS::strdup, so we need to use free
86 // instead of delete.
87 ACE_OS::free (buf);
89 if (i != 0)
91 *os << ", ";
94 *os << "public virtual "
95 << amh_name.c_str ()
96 << be_nl;
99 else
101 // We don't inherit from another user defined object, hence our
102 // base class is the ServantBase class.
103 *os << "public virtual PortableServer::ServantBase";
106 *os << be_uidt << be_uidt_nl
107 << "{" << be_nl
108 << "protected:" << be_idt_nl
109 << class_name.c_str () << " ();" << be_uidt_nl << be_nl
110 << "public:" << be_idt_nl;
112 // No copy constructor for locality constraint interface.
113 *os << class_name.c_str () << " (const " << class_name.c_str ()
114 << "& rhs);" << be_nl
115 << "virtual ~" << class_name.c_str () << " () = default;\n\n"
116 << be_nl
117 << "virtual ::CORBA::Boolean _is_a (const char* logical_type_id);" << be_nl_2;
119 // Add the dispatch method.
120 *os << "virtual void _dispatch (" << be_idt << be_idt_nl
121 << "TAO_ServerRequest &req," << be_nl
122 << "TAO::Portable_Server::Servant_Upcall *_servant_upcall);" << be_uidt
123 << be_uidt_nl << be_nl;
125 this->this_method (node);
127 // The _interface_repository_id method.
128 *os << be_nl
129 << "virtual const char* _interface_repository_id "
130 << "() const;";
132 if (this->visit_scope (node) == -1)
134 ACE_ERROR_RETURN ((LM_ERROR,
135 "(%N:%l) be_visitor_amh_interface_sh::"
136 "visit_interface - "
137 "codegen for scope failed\n"),
138 -1);
141 *os << be_uidt_nl
142 << "};";
144 return 0;
148 be_visitor_amh_interface_sh::visit_operation (be_operation *node)
150 be_visitor_amh_operation_sh visitor (this->ctx_);
151 return visitor.visit_operation (node);
155 be_visitor_amh_interface_sh::visit_attribute (be_attribute *node)
157 be_visitor_amh_operation_sh visitor (this->ctx_);
158 return visitor.visit_attribute (node);
162 be_visitor_amh_interface_sh::add_original_members (be_interface *node,
163 be_interface *amh_node)
165 if (!node || !amh_node)
167 return -1;
170 this->elem_number_ = 0;
172 for (UTL_ScopeActiveIterator si (node, UTL_Scope::IK_decls);
173 !si.is_done ();
174 si.next ())
176 AST_Decl *d = si.item ();
178 if (!d)
180 ACE_ERROR_RETURN ((
181 LM_ERROR,
182 "(%N:%l) be_visitor_amh_pre_proc::visit_interface - "
183 "bad node in this scope\n"
189 if (d->node_type () == AST_Decl::NT_attr)
191 be_attribute *attribute = dynamic_cast<be_attribute*> (d);
193 if (!attribute)
195 return 0;
198 else
200 be_operation* operation = dynamic_cast<be_operation*> (d);
202 if (operation)
204 this->add_amh_operation (operation, amh_node);
209 return 0;
214 be_visitor_amh_interface_sh::add_amh_operation (be_operation *node,
215 be_interface *amh_node)
217 if (!node || !amh_node)
219 return -1;
222 // We do nothing for oneways!
223 if (node->flags () == AST_Operation::OP_oneway)
225 return 0;
228 Identifier *id = nullptr;
229 UTL_ScopedName *sn = nullptr;
231 ACE_NEW_RETURN (id,
232 Identifier ("void"),
233 -1);
235 ACE_NEW_RETURN (sn,
236 UTL_ScopedName (id,
237 nullptr),
238 -1);
240 // Create the return type, which is "void"
241 be_predefined_type *rt = nullptr;
242 ACE_NEW_RETURN (rt,
243 be_predefined_type (AST_PredefinedType::PT_void,
244 sn),
245 -1);
247 ACE_CString original_op_name (
248 node->name ()->last_component ()->get_string ()
251 UTL_ScopedName *op_name =
252 static_cast<UTL_ScopedName *> (amh_node->name ()->copy ());
254 ACE_NEW_RETURN (id,
255 Identifier (original_op_name.rep ()),
256 -1);
258 ACE_NEW_RETURN (sn,
259 UTL_ScopedName (id,
260 nullptr),
261 -1);
263 op_name->nconc (sn);
265 // Create the operation
266 be_operation *operation = nullptr;
267 ACE_NEW_RETURN (operation,
268 be_operation (rt, //node->return_type (),
269 AST_Operation::OP_noflags,
270 op_name,
273 -1);
275 operation->set_name (op_name);
277 // Iterate over the arguments and put all the in and inout
278 // into the new method.
279 if (node->nmembers () > 0)
281 // Initialize an iterator to iterate thru our scope.
282 for (UTL_ScopeActiveIterator si (node, UTL_Scope::IK_decls);
283 !si.is_done ();
284 si.next ())
286 AST_Decl *d = si.item ();
288 if (!d)
290 operation->destroy ();
291 delete operation;
292 operation = nullptr;
294 ACE_ERROR_RETURN ((LM_ERROR,
295 ACE_TEXT ("be_visitor_amh_pre_proc::")
296 ACE_TEXT ("create_response_handler_operation - ")
297 ACE_TEXT ("bad node in this scope\n")),
298 -1);
301 AST_Argument *original_arg =
302 dynamic_cast<AST_Argument*> (d);
304 if (original_arg->direction () == AST_Argument::dir_INOUT ||
305 original_arg->direction () == AST_Argument::dir_IN)
307 // Create the argument.
308 be_argument *arg = nullptr;
309 ACE_NEW_RETURN (arg,
310 be_argument (original_arg->direction (),
311 original_arg->field_type (),
312 original_arg->name ()),
313 -1);
315 operation->be_add_argument (arg);
320 operation->set_defined_in (amh_node);
322 // After having generated the operation we insert it into the
323 // AMH node interface.
324 if (nullptr == amh_node->be_add_operation (operation))
326 return -1;
329 return 0;
333 be_interface *
334 be_visitor_amh_interface_sh::create_amh_class (ACE_CString name)
336 Identifier *id = nullptr;
337 ACE_NEW_RETURN (id,
338 Identifier (name.c_str ()),
339 nullptr);
341 UTL_ScopedName *amh_class_name = nullptr;
342 ACE_NEW_RETURN (amh_class_name,
343 UTL_ScopedName (id,
344 nullptr),
345 nullptr);
347 be_interface *amh_class = nullptr;
348 ACE_NEW_RETURN (amh_class,
349 be_interface (amh_class_name, // name
350 nullptr, // list of inherited
351 0, // number of inherited
352 nullptr, // list of ancestors
353 0, // number of ancestors
354 0, // non-local
355 0), // non-abstract
356 nullptr);
358 amh_class->set_name (amh_class_name);
359 return amh_class;
362 void
363 be_visitor_amh_interface_sh::this_method (be_interface *node)
365 TAO_OutStream *os = this->ctx_->stream ();
367 ACE_CString non_amh_name = node->client_enclosing_scope ();
368 non_amh_name += node->local_name ();
370 // Print out the _this() method. The _this() method for AMH
371 // interfaces is "special", because the returned type is not exactly
372 // the type of the class, but the original class that "implied" the
373 // AMH one.
374 *os << non_amh_name.c_str () << " *_this ();\n" << be_uidt;