2 //=============================================================================
6 * Visitor for generation of code for Attribute
8 * @author Aniruddha Gokhale
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
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
),
44 exec_class_extension_ ("_exec_i")
48 be_visitor_attribute::~be_visitor_attribute (void)
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 ()),
67 UTL_ScopedName
*op_ln
= 0;
68 ACE_NEW_RETURN (op_ln
,
69 UTL_ScopedName (op_id
, 0),
72 UTL_ScopedName
*op_sn
=
73 static_cast<UTL_ScopedName
*> (d
->name ()->copy ());
76 // first the "get" operation
77 be_operation
get_op (node
->field_type (),
78 AST_Operation::OP_noflags
,
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_
);
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
);
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
);
113 case TAO_CodeGen::TAO_ROOT_SH
:
115 be_visitor_operation_sh
visitor (&ctx
);
116 status
= get_op
.accept (&visitor
);
119 case TAO_CodeGen::TAO_ROOT_IH
:
121 be_visitor_operation_ih
visitor (&ctx
);
122 status
= get_op
.accept (&visitor
);
125 case TAO_CodeGen::TAO_ROOT_SS
:
127 be_visitor_operation_ss
visitor (&ctx
);
128 status
= get_op
.accept (&visitor
);
131 case TAO_CodeGen::TAO_ROOT_IS
:
133 be_visitor_operation_is
visitor (&ctx
);
134 status
= get_op
.accept (&visitor
);
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
);
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
);
149 case TAO_CodeGen::TAO_INTERFACE_SMART_PROXY_CH
:
151 be_visitor_operation_smart_proxy_ch
visitor (&ctx
);
152 status
= get_op
.accept (&visitor
);
155 case TAO_CodeGen::TAO_INTERFACE_SMART_PROXY_CS
:
157 be_visitor_operation_smart_proxy_cs
visitor (&ctx
);
158 status
= get_op
.accept (&visitor
);
161 case TAO_CodeGen::TAO_ROOT_TIE_SH
:
163 be_visitor_operation_tie_sh
visitor (&ctx
);
164 status
= get_op
.accept (&visitor
);
167 case TAO_CodeGen::TAO_ROOT_TIE_SS
:
169 be_visitor_operation_tie_ss
visitor (&ctx
);
170 status
= get_op
.accept (&visitor
);
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
);
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
);
188 case TAO_CodeGen::TAO_ROOT_EXH
:
190 be_visitor_operation_ch
visitor (&ctx
);
191 status
= get_op
.accept (&visitor
);
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
);
202 case TAO_CodeGen::TAO_ROOT_CNH
:
203 case TAO_CodeGen::TAO_ROOT_CNS
:
213 ACE_ERROR_RETURN ((LM_ERROR
,
214 "(%N:%l) be_visitor_attribute::"
216 "codegen for get_attribute failed\n"),
220 // Do nothing for readonly attributes.
221 if (node
->readonly ())
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
,
238 // Argument type is the same as the attribute type.
240 idl_global
->gen ()->create_argument (AST_Argument::dir_IN
,
244 arg
->set_name ((UTL_IdList
*) node
->name ()->copy ());
246 // Create the operation.
247 be_operation
set_op (&rt
,
248 AST_Operation::OP_noflags
,
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 ());
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
);
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
);
284 case TAO_CodeGen::TAO_ROOT_SH
:
286 be_visitor_operation_sh
visitor (&ctx
);
287 status
= set_op
.accept (&visitor
);
290 case TAO_CodeGen::TAO_ROOT_IH
:
292 be_visitor_operation_ih
visitor (&ctx
);
293 status
= set_op
.accept (&visitor
);
296 case TAO_CodeGen::TAO_ROOT_SS
:
298 be_visitor_operation_ss
visitor (&ctx
);
299 status
= set_op
.accept (&visitor
);
302 case TAO_CodeGen::TAO_ROOT_IS
:
304 be_visitor_operation_is
visitor (&ctx
);
305 status
= set_op
.accept (&visitor
);
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
);
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
);
320 case TAO_CodeGen::TAO_INTERFACE_SMART_PROXY_CH
:
322 be_visitor_operation_smart_proxy_ch
visitor (&ctx
);
323 status
= set_op
.accept (&visitor
);
326 case TAO_CodeGen::TAO_INTERFACE_SMART_PROXY_CS
:
328 be_visitor_operation_smart_proxy_cs
visitor (&ctx
);
329 status
= set_op
.accept (&visitor
);
332 case TAO_CodeGen::TAO_ROOT_TIE_SH
:
334 be_visitor_operation_tie_sh
visitor (&ctx
);
335 status
= set_op
.accept (&visitor
);
338 case TAO_CodeGen::TAO_ROOT_TIE_SS
:
340 be_visitor_operation_tie_ss
visitor (&ctx
);
341 status
= set_op
.accept (&visitor
);
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
);
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
);
359 case TAO_CodeGen::TAO_ROOT_EXH
:
361 be_visitor_operation_ch
visitor (&ctx
);
362 status
= set_op
.accept (&visitor
);
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
);
373 case TAO_CodeGen::TAO_ROOT_CNH
:
374 case TAO_CodeGen::TAO_ROOT_CNS
:
380 ACE_ERROR_RETURN ((LM_ERROR
,
381 "(%N:%l) be_visitor_attribute::"
383 "bad codegen state\n"),
394 else if (status
== -1)
399 ACE_ERROR_RETURN ((LM_ERROR
,
400 "(%N:%l) be_visitor_attribute::"
402 "codegen for get_attribute failed\n"),
413 be_visitor_attribute::for_facets (bool val
)
415 this->for_facets_
= val
;
419 be_visitor_attribute::op_scope (be_decl
*node
)
421 this->op_scope_
= node
;
425 be_visitor_attribute::exec_class_extension (const char *extension
)
427 this->exec_class_extension_
= extension
;