ACE+TAO-6_5_14
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_interface / amh_sh.cpp
blob51de355c8ff8c13d4affa52aca9ce85639c230d1
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 (void)
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 () != 0)
39 return 0;
42 TAO_OutStream *os = this->ctx_->stream ();
43 ACE_CString class_name;
45 *os << be_nl_2 << "// TAO_IDL - Generated from" << be_nl
46 << "// " << __FILE__ << ":" << __LINE__ << be_nl_2;
48 // We shall have a POA_ prefix only if we are at the topmost level.
49 if (!node->is_nested ())
51 // We are outermost.
52 class_name += "POA_AMH_";
53 class_name += node->local_name ();
55 else
57 class_name += "AMH_";
58 class_name += node->local_name ();
61 // Generate the skeleton class name.
62 *os << "class " << class_name.c_str () << ";" << be_nl;
64 // Generate the _ptr declaration.
65 *os << "typedef " << class_name.c_str () << " *" << class_name.c_str ()
66 << "_ptr;" << be_nl_2;
68 // Now generate the class definition.
69 *os << "class " << be_global->skel_export_macro ()
70 << " " << class_name.c_str () << be_idt_nl << ": " << be_idt;
72 long n_parents = node->n_inherits ();
74 if (n_parents > 0)
76 for (int i = 0; i < n_parents; ++i)
78 ACE_CString amh_name ("POA_");
80 // @@ The following code is *NOT* exception-safe.
81 char *buf = 0;
82 be_interface *base =
83 dynamic_cast<be_interface*> (node->inherits ()[i]);
84 base->compute_full_name ("AMH_", "", buf);
85 amh_name += buf;
86 // buf was allocated by ACE_OS::strdup, so we need to use free
87 // instead of delete.
88 ACE_OS::free (buf);
90 if (i != 0)
92 *os << ", ";
95 *os << "public virtual "
96 << amh_name.c_str ()
97 << be_nl;
100 else
102 // We don't inherit from another user defined object, hence our
103 // base class is the ServantBase class.
104 *os << "public virtual PortableServer::ServantBase";
107 *os << be_uidt << be_uidt_nl
108 << "{" << be_nl
109 << "protected:" << be_idt_nl
110 << class_name.c_str () << " (void);" << be_uidt_nl << be_nl
111 << "public:" << be_idt_nl;
113 // No copy constructor for locality constraint interface.
114 *os << class_name.c_str () << " (const " << class_name.c_str ()
115 << "& rhs);" << be_nl
116 << "virtual ~" << class_name.c_str () << " (void);\n\n"
117 << be_nl
118 << "virtual ::CORBA::Boolean _is_a (const char* logical_type_id);" << be_nl_2;
120 // Add the dispatch method.
121 *os << "virtual void _dispatch (" << be_idt << be_idt_nl
122 << "TAO_ServerRequest &req," << be_nl
123 << "TAO::Portable_Server::Servant_Upcall *_servant_upcall);" << be_uidt
124 << be_uidt_nl << be_nl;
126 this->this_method (node);
128 // The _interface_repository_id method.
129 *os << be_nl
130 << "virtual const char* _interface_repository_id "
131 << "(void) const;";
133 if (this->visit_scope (node) == -1)
135 ACE_ERROR_RETURN ((LM_ERROR,
136 "(%N:%l) be_visitor_amh_interface_sh::"
137 "visit_interface - "
138 "codegen for scope failed\n"),
139 -1);
142 *os << be_uidt_nl
143 << "};";
145 return 0;
149 be_visitor_amh_interface_sh::visit_operation (be_operation *node)
151 be_visitor_amh_operation_sh visitor (this->ctx_);
152 return visitor.visit_operation (node);
156 be_visitor_amh_interface_sh::visit_attribute (be_attribute *node)
158 be_visitor_amh_operation_sh visitor (this->ctx_);
159 return visitor.visit_attribute (node);
163 be_visitor_amh_interface_sh::add_original_members (be_interface *node,
164 be_interface *amh_node)
166 if (!node || !amh_node)
168 return -1;
171 this->elem_number_ = 0;
173 for (UTL_ScopeActiveIterator si (node, UTL_Scope::IK_decls);
174 !si.is_done ();
175 si.next ())
177 AST_Decl *d = si.item ();
179 if (!d)
181 ACE_ERROR_RETURN ((
182 LM_ERROR,
183 "(%N:%l) be_visitor_amh_pre_proc::visit_interface - "
184 "bad node in this scope\n"
190 if (d->node_type () == AST_Decl::NT_attr)
192 be_attribute *attribute = dynamic_cast<be_attribute*> (d);
194 if (!attribute)
196 return 0;
199 else
201 be_operation* operation = dynamic_cast<be_operation*> (d);
203 if (operation)
205 this->add_amh_operation (operation, amh_node);
210 return 0;
215 be_visitor_amh_interface_sh::add_amh_operation (be_operation *node,
216 be_interface *amh_node)
218 if (!node || !amh_node)
220 return -1;
223 // We do nothing for oneways!
224 if (node->flags () == AST_Operation::OP_oneway)
226 return 0;
229 Identifier *id = 0;
230 UTL_ScopedName *sn = 0;
232 ACE_NEW_RETURN (id,
233 Identifier ("void"),
234 -1);
236 ACE_NEW_RETURN (sn,
237 UTL_ScopedName (id,
239 -1);
241 // Create the return type, which is "void"
242 be_predefined_type *rt = 0;
243 ACE_NEW_RETURN (rt,
244 be_predefined_type (AST_PredefinedType::PT_void,
245 sn),
246 -1);
248 ACE_CString original_op_name (
249 node->name ()->last_component ()->get_string ()
252 UTL_ScopedName *op_name =
253 static_cast<UTL_ScopedName *> (amh_node->name ()->copy ());
255 ACE_NEW_RETURN (id,
256 Identifier (original_op_name.rep ()),
257 -1);
259 ACE_NEW_RETURN (sn,
260 UTL_ScopedName (id,
262 -1);
264 op_name->nconc (sn);
266 // Create the operation
267 be_operation *operation = 0;
268 ACE_NEW_RETURN (operation,
269 be_operation (rt, //node->return_type (),
270 AST_Operation::OP_noflags,
271 op_name,
274 -1);
276 operation->set_name (op_name);
278 // Iterate over the arguments and put all the in and inout
279 // into the new method.
280 if (node->nmembers () > 0)
282 // Initialize an iterator to iterate thru our scope.
283 for (UTL_ScopeActiveIterator si (node, UTL_Scope::IK_decls);
284 !si.is_done ();
285 si.next ())
287 AST_Decl *d = si.item ();
289 if (!d)
291 operation->destroy ();
292 delete operation;
293 operation = 0;
295 ACE_ERROR_RETURN ((LM_ERROR,
296 ACE_TEXT ("be_visitor_amh_pre_proc::")
297 ACE_TEXT ("create_response_handler_operation - ")
298 ACE_TEXT ("bad node in this scope\n")),
299 -1);
303 AST_Argument *original_arg =
304 dynamic_cast<AST_Argument*> (d);
306 if (original_arg->direction () == AST_Argument::dir_INOUT ||
307 original_arg->direction () == AST_Argument::dir_IN)
309 // Create the argument.
310 be_argument *arg = 0;
311 ACE_NEW_RETURN (arg,
312 be_argument (original_arg->direction (),
313 original_arg->field_type (),
314 original_arg->name ()),
315 -1);
317 operation->be_add_argument (arg);
322 operation->set_defined_in (amh_node);
324 // After having generated the operation we insert it into the
325 // AMH node interface.
326 if (0 == amh_node->be_add_operation (operation))
328 return -1;
331 return 0;
335 be_interface *
336 be_visitor_amh_interface_sh::create_amh_class (ACE_CString name)
338 Identifier *id = 0;
339 ACE_NEW_RETURN (id,
340 Identifier (name.c_str ()),
343 UTL_ScopedName *amh_class_name = 0;
344 ACE_NEW_RETURN (amh_class_name,
345 UTL_ScopedName (id,
349 be_interface *amh_class = 0;
350 ACE_NEW_RETURN (amh_class,
351 be_interface (amh_class_name, // name
352 0, // list of inherited
353 0, // number of inherited
354 0, // list of ancestors
355 0, // number of ancestors
356 0, // non-local
357 0), // non-abstract
360 amh_class->set_name (amh_class_name);
361 return amh_class;
364 void
365 be_visitor_amh_interface_sh::this_method (be_interface *node)
367 TAO_OutStream *os = this->ctx_->stream ();
369 ACE_CString non_amh_name = node->client_enclosing_scope ();
370 non_amh_name += node->local_name ();
372 // Print out the _this() method. The _this() method for AMH
373 // interfaces is "special", because the returned type is not exactly
374 // the type of the class, but the original class that "implied" the
375 // AMH one.
376 *os << non_amh_name.c_str () << " *_this (void);\n" << be_uidt;