2 //=============================================================================
6 * Visitor generating code for Arrays in the client inline.
8 * @author Aniruddha Gokhale
10 //=============================================================================
14 be_visitor_array_ci::be_visitor_array_ci (be_visitor_context
*ctx
)
15 : be_visitor_array (ctx
)
19 int be_visitor_array_ci::visit_array (be_array
*node
)
21 // Nothing to do if we are imported or code is already generated.
22 if (node
->imported () || node
->cli_inline_gen ())
27 this->ctx_
->node (node
); // save the array node
29 // If we contain an anonymous sequence, generate code for it here.
30 be_type
*bt
= dynamic_cast<be_type
*> (node
->base_type ());
34 ACE_ERROR_RETURN ((LM_ERROR
,
35 "(%N:%l) be_visitor_array_ci::"
41 AST_Decl::NodeType nt
= bt
->node_type ();
43 if (nt
== AST_Decl::NT_sequence
)
45 if (this->gen_anonymous_base_type (bt
,
46 TAO_CodeGen::TAO_ROOT_CI
)
49 ACE_ERROR_RETURN ((LM_ERROR
,
50 "(%N:%l) be_visitor_array_ci::"
52 "gen_anonymous_base_type failed\n"),
57 // If the array is an anonymous member and if its element type
58 // is a declaration (not a reference), we must generate code for
60 if (this->ctx_
->alias () == nullptr // Not a typedef.
61 && bt
->is_child (this->ctx_
->scope ()->decl ()))
64 be_visitor_context
ctx (*this->ctx_
);
68 case AST_Decl::NT_struct
:
70 be_visitor_structure_ci
sc_visitor (&ctx
);
71 status
= bt
->accept (&sc_visitor
);
74 case AST_Decl::NT_union
:
76 be_visitor_union_ci
uc_visitor (&ctx
);
77 status
= bt
->accept (&uc_visitor
);
86 ACE_ERROR_RETURN ((LM_ERROR
,
87 "(%N:%l) be_visitor_array_ch::"
89 "array base type codegen failed\n"),
94 // To hold the full and local.
95 char fname
[NAMEBUFSIZE
];
96 char lname
[NAMEBUFSIZE
];
97 ACE_OS::memset (fname
,
100 ACE_OS::memset (lname
,
104 if (this->ctx_
->tdef ())
107 ACE_OS::sprintf (fname
, "%s",
109 ACE_OS::sprintf (lname
, "%s",
110 node
->local_name ()->get_string ());
114 // For anonymous arrays ...
115 // we have to generate a name for us that has an underscope prepended to
116 // our local name. This needs to be inserted after the parents's name.
117 if (node
->is_nested ())
120 dynamic_cast<be_scope
*> (node
->defined_in ())->decl ();
121 ACE_OS::sprintf (fname
,
123 parent
->full_name (),
124 node
->local_name ()->get_string ());
125 ACE_OS::sprintf (lname
,
127 node
->local_name ()->get_string ());
131 ACE_OS::sprintf (fname
,
134 ACE_OS::sprintf (lname
,
136 node
->local_name ()->get_string ());
140 TAO_OutStream
*os
= this->ctx_
->stream ();
142 TAO_INSERT_COMMENT (os
);
144 // Generate the array traits specialization definitions,
145 // guarded by #ifdef on unaliased array element type and length.
149 if (nt
== AST_Decl::NT_typedef
)
151 be_typedef
*td
= dynamic_cast<be_typedef
*> (bt
);
152 unique
= td
->primitive_base_type ()->flat_name ();
156 unique
= bt
->flat_name ();
159 char buf
[NAMEBUFSIZE
];
162 for (i
= 0UL; i
< node
->n_dims (); ++i
)
167 ACE_OS::sprintf (buf
,
168 "_" ACE_UINT32_FORMAT_SPECIFIER_ASCII
,
169 node
->dims ()[i
]->ev ()->u
.ulval
);
176 << be_global
->core_versioning_begin ();
179 << "ACE_INLINE" << be_nl
181 << "TAO::Array_Traits<" << fname
<< "_forany>::free ("
182 << be_idt
<< be_idt_nl
183 << fname
<< "_slice * _tao_slice)" << be_uidt
<< be_uidt_nl
185 << fname
<< "_free (_tao_slice);" << be_uidt_nl
189 << "ACE_INLINE" << be_nl
190 << fname
<< "_slice *" << be_nl
191 << "TAO::Array_Traits<" << fname
<< "_forany>::dup ("
192 << be_idt
<< be_idt_nl
193 << "const " << fname
<< "_slice * _tao_slice)" << be_uidt
<< be_uidt_nl
195 << "return " << fname
<< "_dup (_tao_slice);" << be_uidt_nl
199 << "ACE_INLINE" << be_nl
201 << "TAO::Array_Traits<" << fname
<< "_forany>::copy ("
202 << be_idt
<< be_idt_nl
203 << fname
<< "_slice * _tao_to," << be_nl
204 << "const " << fname
<< "_slice * _tao_from)" << be_uidt
<< be_uidt_nl
206 << fname
<< "_copy (_tao_to, _tao_from);" << be_uidt_nl
210 << "ACE_INLINE" << be_nl
212 << "TAO::Array_Traits<" << fname
<< "_forany>::zero ("
213 << be_idt
<< be_idt_nl
214 << fname
<< "_slice * _tao_slice)" << be_uidt
<< be_uidt_nl
217 ACE_CDR::ULong ndims
= node
->n_dims ();
218 be_array
*primitive_type
= nullptr;
220 if (bt
->node_type () == AST_Decl::NT_typedef
)
222 // Base type of the array node is a typedef. We need to make sure that
223 // this typedef is not to another array type. If it is, then we cannot
224 // assign an array to another. We will have to invoke the underlying
225 // array type's copy method for every array dimension.
227 // There may be more than one level of typedef.
230 while (tmp
->node_type () == AST_Decl::NT_typedef
)
232 be_typedef
*tdef
= dynamic_cast<be_typedef
*> (tmp
);
233 tmp
= dynamic_cast<be_type
*> (tdef
->base_type ());
236 primitive_type
= dynamic_cast<be_array
*> (tmp
);
239 *os
<< "// Zero each individual element." << be_nl
;
241 // Generate nested loops for as many dimensions as there are.
242 for (i
= 0; i
< ndims
; ++i
)
244 // Retrieve the ith dimension value.
245 AST_Expression
*expr
= node
->dims ()[i
];
247 if ((expr
== nullptr) || ((expr
!= nullptr) && (expr
->ev () == nullptr)))
249 ACE_ERROR_RETURN ((LM_ERROR
,
250 "(%N:%l) be_visitor_array_cs::"
252 "bad array dimension\n"),
256 if (expr
->ev ()->et
== AST_Expression::EV_ulong
)
258 // Generate a loop for each dimension.
259 *os
<< "for (::CORBA::ULong i" << i
<< " = 0; i" << i
<< " < "
260 << expr
->ev ()->u
.ulval
<< "; ++i" << i
<< ")" << be_idt_nl
265 ACE_ERROR_RETURN ((LM_ERROR
,
266 "(%N:%l) be_visitor_array_cs::"
268 "bad array dimension value\n"),
275 // The base type is a typedef to another array type, so
276 // we use the base type's copy method.
277 *os
<< "// call the underlying _zero" << be_nl
;
279 * os
<< "TAO::Array_Traits< ";
281 if (bt
->accept (this) == -1)
283 ACE_ERROR_RETURN ((LM_ERROR
,
284 "be_visitor_array_cs::"
286 "base type decl failed\n"),
294 *os
<< "zero (_tao_slice";
296 for (i
= 0; i
< ndims
; ++i
)
298 *os
<< "[i" << i
<< "]";
305 // The base type is not a typedef to possibly another array type. In
306 // such a case, assign each element.
310 for (i
= 0; i
< ndims
; ++i
)
312 *os
<< "[i" << i
<< "]";
317 if (bt
->accept (this) == -1)
319 ACE_ERROR_RETURN ((LM_ERROR
,
320 "be_visitor_array_ch::"
322 "base type decl failed\n"),
329 for (i
= 0; i
< ndims
; ++i
)
331 // Add closing braces as many times as the number of dimensions.
332 *os
<< be_uidt_nl
<< "}" << be_uidt
;
334 *os
<< be_uidt_nl
<< "}";
337 << "ACE_INLINE" << be_nl
338 << fname
<< "_slice *" << be_nl
339 << "TAO::Array_Traits<" << fname
<< "_forany>::alloc ()"
340 << be_idt
<< be_uidt_nl
342 << "return " << fname
<< "_alloc ();" << be_uidt_nl
348 << be_global
->core_versioning_end ();
350 node
->cli_inline_gen (true);