Merge pull request #2317 from jwillemsen/jwi-deleteop
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_array / array_ci.cpp
blobeccbf54150509c6da3b216be52fb0783ac406b96
2 //=============================================================================
3 /**
4 * @file array_ci.cpp
6 * Visitor generating code for Arrays in the client inline.
8 * @author Aniruddha Gokhale
9 */
10 //=============================================================================
12 #include "array.h"
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 ())
24 return 0;
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 ());
32 if (!bt)
34 ACE_ERROR_RETURN ((LM_ERROR,
35 "(%N:%l) be_visitor_array_ci::"
36 "visit_array - "
37 "bad base type\n"),
38 -1);
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)
47 == -1)
49 ACE_ERROR_RETURN ((LM_ERROR,
50 "(%N:%l) be_visitor_array_ci::"
51 "visit_array - "
52 "gen_anonymous_base_type failed\n"),
53 -1);
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
59 // the declaration.
60 if (this->ctx_->alias () == nullptr // Not a typedef.
61 && bt->is_child (this->ctx_->scope ()->decl ()))
63 int status = 0;
64 be_visitor_context ctx (*this->ctx_);
66 switch (nt)
68 case AST_Decl::NT_struct:
70 be_visitor_structure_ci sc_visitor (&ctx);
71 status = bt->accept (&sc_visitor);
72 break;
74 case AST_Decl::NT_union:
76 be_visitor_union_ci uc_visitor (&ctx);
77 status = bt->accept (&uc_visitor);
78 break;
80 default:
81 break;
84 if (status == -1)
86 ACE_ERROR_RETURN ((LM_ERROR,
87 "(%N:%l) be_visitor_array_ch::"
88 "visit_array - "
89 "array base type codegen failed\n"),
90 -1);
94 // To hold the full and local.
95 char fname [NAMEBUFSIZE];
96 char lname [NAMEBUFSIZE];
97 ACE_OS::memset (fname,
98 '\0',
99 NAMEBUFSIZE);
100 ACE_OS::memset (lname,
101 '\0',
102 NAMEBUFSIZE);
104 if (this->ctx_->tdef ())
106 // Typedefed node.
107 ACE_OS::sprintf (fname, "%s",
108 node->full_name ());
109 ACE_OS::sprintf (lname, "%s",
110 node->local_name ()->get_string ());
112 else
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 ())
119 be_decl *parent =
120 dynamic_cast<be_scope*> (node->defined_in ())->decl ();
121 ACE_OS::sprintf (fname,
122 "%s::_%s",
123 parent->full_name (),
124 node->local_name ()->get_string ());
125 ACE_OS::sprintf (lname,
126 "_%s",
127 node->local_name ()->get_string ());
129 else
131 ACE_OS::sprintf (fname,
132 "_%s",
133 node->full_name ());
134 ACE_OS::sprintf (lname,
135 "_%s",
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.
147 ACE_CString unique;
149 if (nt == AST_Decl::NT_typedef)
151 be_typedef *td = dynamic_cast<be_typedef*> (bt);
152 unique = td->primitive_base_type ()->flat_name ();
154 else
156 unique = bt->flat_name ();
159 char buf[NAMEBUFSIZE];
160 ACE_CDR::ULong i;
162 for (i = 0UL; i < node->n_dims (); ++i)
164 ACE_OS::memset (buf,
165 '\0',
166 NAMEBUFSIZE);
167 ACE_OS::sprintf (buf,
168 "_" ACE_UINT32_FORMAT_SPECIFIER_ASCII,
169 node->dims ()[i]->ev ()->u.ulval);
170 unique += buf;
173 unique += "_traits";
175 *os << be_nl
176 << be_global->core_versioning_begin ();
178 *os << be_nl_2
179 << "ACE_INLINE" << be_nl
180 << "void" << 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
184 << "{" << be_idt_nl
185 << fname << "_free (_tao_slice);" << be_uidt_nl
186 << "}";
188 *os << be_nl_2
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
194 << "{" << be_idt_nl
195 << "return " << fname << "_dup (_tao_slice);" << be_uidt_nl
196 << "}";
198 *os << be_nl_2
199 << "ACE_INLINE" << be_nl
200 << "void" << 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
205 << "{" << be_idt_nl
206 << fname << "_copy (_tao_to, _tao_from);" << be_uidt_nl
207 << "}";
209 *os << be_nl_2
210 << "ACE_INLINE" << be_nl
211 << "void" << 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
215 << "{" << be_idt_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.
228 be_type *tmp = bt;
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::"
251 "visit_array - "
252 "bad array dimension\n"),
253 -1);
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
261 << "{" << be_idt_nl;
263 else
265 ACE_ERROR_RETURN ((LM_ERROR,
266 "(%N:%l) be_visitor_array_cs::"
267 "visit_array - "
268 "bad array dimension value\n"),
269 -1);
273 if (primitive_type)
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::"
285 "visit_array - "
286 "base type decl failed\n"),
287 -1);
290 * os << "_forany";
292 * os << ">::";
294 *os << "zero (_tao_slice";
296 for (i = 0; i < ndims; ++i)
298 *os << "[i" << i << "]";
301 *os << ");";
303 else
305 // The base type is not a typedef to possibly another array type. In
306 // such a case, assign each element.
308 *os << "_tao_slice";
310 for (i = 0; i < ndims; ++i)
312 *os << "[i" << i << "]";
315 *os << " = ";
317 if (bt->accept (this) == -1)
319 ACE_ERROR_RETURN ((LM_ERROR,
320 "be_visitor_array_ch::"
321 "visit_array - "
322 "base type decl failed\n"),
323 -1);
326 *os << " ();";
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 << "}";
336 *os << be_nl_2
337 << "ACE_INLINE" << be_nl
338 << fname << "_slice *" << be_nl
339 << "TAO::Array_Traits<" << fname << "_forany>::alloc ()"
340 << be_idt << be_uidt_nl
341 << "{" << be_idt_nl
342 << "return " << fname << "_alloc ();" << be_uidt_nl
343 << "}";
345 *os << be_nl;
347 *os << be_nl
348 << be_global->core_versioning_end ();
350 node->cli_inline_gen (true);
351 return 0;