Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_attribute / attribute.cpp
blob77337f29a7396cddfb0e479045d4562416cbdde3
2 //=============================================================================
3 /**
4 * @file attribute.cpp
6 * Visitor for generation of code for Attribute
8 * @author Aniruddha Gokhale
9 */
10 //=============================================================================
12 #include "attribute.h"
14 // Attribute gets mapped to one or possibly two operations based on whether
15 // it is readonly or not. The two operations "get" and "set" the value of the
16 // attribute.
18 // code generation for attributes is achieved by mapping an attribute node to
19 // a corresponding operation node. The reason is that we do not want to
20 // duplicate the code. However, an attribute node and an operation node have
21 // different interfaces. Hence we need some form of an adapter that can take us
22 // from an attribute node to an operation node. The following paragraph
23 // describes how this is accomplished.
25 // For a "get" operation on the attribute, we create an operation node with the
26 // same name as the attribute and a return type which is the same as the type
27 // of the attribute. This operation has no arguments.
29 // For a "set" operation on the attribute (if it is not readonly), we create an
30 // operation node with a "void" return type and an "in" parameter of the same
31 // type as the attribute.
33 // In both cases the context will hold sufficient information to indicate that
34 // the operation node is really an attribute node.
36 // *************************************************************************
37 // primary visitor for "attribute". The context state decides the next state
38 // *************************************************************************
40 be_visitor_attribute::be_visitor_attribute (be_visitor_context *ctx)
41 : be_visitor_decl (ctx),
42 for_facets_ (false),
43 op_scope_ (0),
44 exec_class_extension_ ("_exec_i")
48 be_visitor_attribute::~be_visitor_attribute (void)
52 int
53 be_visitor_attribute::visit_attribute (be_attribute *node)
55 this->ctx_->node (node);
56 this->ctx_->attribute (node);
58 UTL_Scope *s = node->defined_in ();
59 AST_Decl *d = ScopeAsDecl (s);
60 ACE_CString op_name (this->ctx_->port_prefix ());
61 op_name += node->local_name ()->get_string ();
62 Identifier *op_id = 0;
63 ACE_NEW_RETURN (op_id,
64 Identifier (op_name.c_str ()),
65 -1);
67 UTL_ScopedName *op_ln = 0;
68 ACE_NEW_RETURN (op_ln,
69 UTL_ScopedName (op_id, 0),
70 -1);
72 UTL_ScopedName *op_sn =
73 static_cast<UTL_ScopedName *> (d->name ()->copy ());
74 op_sn->nconc (op_ln);
76 // first the "get" operation
77 be_operation get_op (node->field_type (),
78 AST_Operation::OP_noflags,
80 node->is_local (),
81 node->is_abstract ());
83 get_op.set_defined_in (s);
84 get_op.set_name (op_sn);
85 UTL_ExceptList *get_exceptions = node->get_get_exceptions ();
87 if (0 != get_exceptions)
89 get_op.be_add_exceptions (get_exceptions->copy ());
92 be_visitor_context ctx (*this->ctx_);
93 int status = 1;
95 switch (this->ctx_->state ())
97 // These two cases are the only ones that could involve a strategy.
98 case TAO_CodeGen::TAO_ROOT_CH:
99 case TAO_CodeGen::TAO_INTERFACE_CH:
101 ctx.state (TAO_CodeGen::TAO_OPERATION_CH);
102 be_visitor_operation_ch visitor (&ctx);
103 status = get_op.accept (&visitor);
104 break;
106 case TAO_CodeGen::TAO_ROOT_CS:
108 ctx.state (TAO_CodeGen::TAO_OPERATION_CS);
109 be_visitor_operation_cs visitor (&ctx);
110 status = get_op.accept (&visitor);
111 break;
113 case TAO_CodeGen::TAO_ROOT_SH:
115 be_visitor_operation_sh visitor (&ctx);
116 status = get_op.accept (&visitor);
117 break;
119 case TAO_CodeGen::TAO_ROOT_IH:
121 be_visitor_operation_ih visitor (&ctx);
122 status = get_op.accept (&visitor);
123 break;
125 case TAO_CodeGen::TAO_ROOT_SS:
127 be_visitor_operation_ss visitor (&ctx);
128 status = get_op.accept (&visitor);
129 break;
131 case TAO_CodeGen::TAO_ROOT_IS:
133 be_visitor_operation_is visitor (&ctx);
134 status = get_op.accept (&visitor);
135 break;
137 case TAO_CodeGen::TAO_INTERFACE_DIRECT_PROXY_IMPL_SH:
139 be_visitor_operation_proxy_impl_xh visitor (&ctx);
140 status = get_op.accept (&visitor);
141 break;
143 case TAO_CodeGen::TAO_INTERFACE_DIRECT_PROXY_IMPL_SS:
145 be_visitor_operation_direct_proxy_impl_ss visitor (&ctx);
146 status = get_op.accept (&visitor);
147 break;
149 case TAO_CodeGen::TAO_INTERFACE_SMART_PROXY_CH:
151 be_visitor_operation_smart_proxy_ch visitor (&ctx);
152 status = get_op.accept (&visitor);
153 break;
155 case TAO_CodeGen::TAO_INTERFACE_SMART_PROXY_CS:
157 be_visitor_operation_smart_proxy_cs visitor (&ctx);
158 status = get_op.accept (&visitor);
159 break;
161 case TAO_CodeGen::TAO_ROOT_TIE_SH:
163 be_visitor_operation_tie_sh visitor (&ctx);
164 status = get_op.accept (&visitor);
165 break;
167 case TAO_CodeGen::TAO_ROOT_TIE_SS:
169 be_visitor_operation_tie_ss visitor (&ctx);
170 status = get_op.accept (&visitor);
171 break;
173 case TAO_CodeGen::TAO_ROOT_SVTH:
174 case TAO_CodeGen::TAO_ROOT_SVH:
176 be_visitor_operation_ch visitor (&ctx);
177 status = get_op.accept (&visitor);
178 break;
180 case TAO_CodeGen::TAO_ROOT_SVTS:
181 case TAO_CodeGen::TAO_ROOT_SVS:
183 be_visitor_operation_svs visitor (&ctx);
184 visitor.scope (this->op_scope_);
185 status = get_op.accept (&visitor);
186 break;
188 case TAO_CodeGen::TAO_ROOT_EXH:
190 be_visitor_operation_ch visitor (&ctx);
191 status = get_op.accept (&visitor);
192 break;
194 case TAO_CodeGen::TAO_ROOT_EXS:
196 be_visitor_operation_exs visitor (&ctx);
197 visitor.scope (this->op_scope_);
198 visitor.class_extension (this->exec_class_extension_.c_str ());
199 status = get_op.accept (&visitor);
200 break;
202 case TAO_CodeGen::TAO_ROOT_CNH:
203 case TAO_CodeGen::TAO_ROOT_CNS:
204 break;
205 default:
206 get_op.destroy ();
207 return 0;
210 if (status == -1)
212 get_op.destroy ();
213 ACE_ERROR_RETURN ((LM_ERROR,
214 "(%N:%l) be_visitor_attribute::"
215 "visit_attribute - "
216 "codegen for get_attribute failed\n"),
217 -1);
220 // Do nothing for readonly attributes.
221 if (node->readonly ())
223 get_op.destroy ();
224 return 0;
227 status = 1;
229 // Create the set method.
230 Identifier id ("void");
231 UTL_ScopedName sn (&id,
234 // The return type is "void".
235 be_predefined_type rt (AST_PredefinedType::PT_void,
236 &sn);
238 // Argument type is the same as the attribute type.
239 AST_Argument *arg =
240 idl_global->gen ()->create_argument (AST_Argument::dir_IN,
241 node->field_type (),
242 node->name ());
244 arg->set_name ((UTL_IdList *) node->name ()->copy ());
246 // Create the operation.
247 be_operation set_op (&rt,
248 AST_Operation::OP_noflags,
250 node->is_local (),
251 node->is_abstract ());
252 set_op.set_defined_in (node->defined_in ());
253 set_op.set_name (static_cast<UTL_ScopedName *> (op_sn->copy ()));
254 set_op.be_add_argument (arg);
256 UTL_ExceptList *set_exceptions = node->get_set_exceptions ();
258 if (0 != set_exceptions)
260 set_op.be_add_exceptions (set_exceptions->copy ());
263 ctx = *this->ctx_;
264 status = 1;
266 switch (this->ctx_->state ())
268 // These two cases are the only ones that could involved a strategy.
269 case TAO_CodeGen::TAO_ROOT_CH:
270 case TAO_CodeGen::TAO_INTERFACE_CH:
272 ctx.state (TAO_CodeGen::TAO_OPERATION_CH);
273 be_visitor_operation_ch visitor (&ctx);
274 status = set_op.accept (&visitor);
275 break;
277 case TAO_CodeGen::TAO_ROOT_CS:
279 ctx.state (TAO_CodeGen::TAO_OPERATION_CS);
280 be_visitor_operation_cs visitor (&ctx);
281 status = set_op.accept (&visitor);
282 break;
284 case TAO_CodeGen::TAO_ROOT_SH:
286 be_visitor_operation_sh visitor (&ctx);
287 status = set_op.accept (&visitor);
288 break;
290 case TAO_CodeGen::TAO_ROOT_IH:
292 be_visitor_operation_ih visitor (&ctx);
293 status = set_op.accept (&visitor);
294 break;
296 case TAO_CodeGen::TAO_ROOT_SS:
298 be_visitor_operation_ss visitor (&ctx);
299 status = set_op.accept (&visitor);
300 break;
302 case TAO_CodeGen::TAO_ROOT_IS:
304 be_visitor_operation_is visitor (&ctx);
305 status = set_op.accept (&visitor);
306 break;
308 case TAO_CodeGen::TAO_INTERFACE_DIRECT_PROXY_IMPL_SH:
310 be_visitor_operation_proxy_impl_xh visitor (&ctx);
311 status = set_op.accept (&visitor);
312 break;
314 case TAO_CodeGen::TAO_INTERFACE_DIRECT_PROXY_IMPL_SS:
316 be_visitor_operation_direct_proxy_impl_ss visitor (&ctx);
317 status = set_op.accept (&visitor);
318 break;
320 case TAO_CodeGen::TAO_INTERFACE_SMART_PROXY_CH:
322 be_visitor_operation_smart_proxy_ch visitor (&ctx);
323 status = set_op.accept (&visitor);
324 break;
326 case TAO_CodeGen::TAO_INTERFACE_SMART_PROXY_CS:
328 be_visitor_operation_smart_proxy_cs visitor (&ctx);
329 status = set_op.accept (&visitor);
330 break;
332 case TAO_CodeGen::TAO_ROOT_TIE_SH:
334 be_visitor_operation_tie_sh visitor (&ctx);
335 status = set_op.accept (&visitor);
336 break;
338 case TAO_CodeGen::TAO_ROOT_TIE_SS:
340 be_visitor_operation_tie_ss visitor (&ctx);
341 status = set_op.accept (&visitor);
342 break;
344 case TAO_CodeGen::TAO_ROOT_SVTH:
345 case TAO_CodeGen::TAO_ROOT_SVH:
347 be_visitor_operation_ch visitor (&ctx);
348 status = set_op.accept (&visitor);
349 break;
351 case TAO_CodeGen::TAO_ROOT_SVTS:
352 case TAO_CodeGen::TAO_ROOT_SVS:
354 be_visitor_operation_svs visitor (&ctx);
355 visitor.scope (this->op_scope_);
356 status = set_op.accept (&visitor);
357 break;
359 case TAO_CodeGen::TAO_ROOT_EXH:
361 be_visitor_operation_ch visitor (&ctx);
362 status = set_op.accept (&visitor);
363 break;
365 case TAO_CodeGen::TAO_ROOT_EXS:
367 be_visitor_operation_exs visitor (&ctx);
368 visitor.scope (this->op_scope_);
369 visitor.class_extension (this->exec_class_extension_.c_str ());
370 status = set_op.accept (&visitor);
371 break;
373 case TAO_CodeGen::TAO_ROOT_CNH:
374 case TAO_CodeGen::TAO_ROOT_CNS:
375 break;
376 default:
377 // Error.
378 set_op.destroy ();
379 rt.destroy ();
380 ACE_ERROR_RETURN ((LM_ERROR,
381 "(%N:%l) be_visitor_attribute::"
382 "visit_attribute - "
383 "bad codegen state\n"),
384 -1);
387 if (status == 0)
389 get_op.destroy ();
390 set_op.destroy ();
391 rt.destroy ();
392 return 0;
394 else if (status == -1)
396 get_op.destroy ();
397 set_op.destroy ();
398 rt.destroy ();
399 ACE_ERROR_RETURN ((LM_ERROR,
400 "(%N:%l) be_visitor_attribute::"
401 "visit_attribute - "
402 "codegen for get_attribute failed\n"),
403 -1);
406 get_op.destroy ();
407 set_op.destroy ();
408 rt.destroy ();
409 return 0;
412 void
413 be_visitor_attribute::for_facets (bool val)
415 this->for_facets_ = val;
418 void
419 be_visitor_attribute::op_scope (be_decl *node)
421 this->op_scope_ = node;
424 void
425 be_visitor_attribute::exec_class_extension (const char *extension)
427 this->exec_class_extension_ = extension;