Changes to attempt to silence bcc64x
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_array / array_cs.cpp
blobb4987cd21c6d7f5ca5a12ecd576ef24548d4e4f7
2 //=============================================================================
3 /**
4 * @file array_cs.cpp
6 * Visitor for code generation of Arrays in the client stubs
8 * @author Aniruddha Gokhale
9 */
10 //=============================================================================
12 #include "array.h"
14 be_visitor_array_cs::be_visitor_array_cs (be_visitor_context *ctx)
15 : be_visitor_array (ctx)
19 int be_visitor_array_cs::visit_array (be_array *node)
21 // Nothing to do if we are imported or code is already generated.
22 if (node->imported () || (node->cli_stub_gen ()))
24 return 0;
27 TAO_OutStream *os = this->ctx_->stream ();
28 ACE_CDR::ULong i;
29 this->ctx_->node (node);
31 // Retrieve the type.
32 be_type *bt = dynamic_cast<be_type*> (node->base_type ());
34 if (!bt)
36 ACE_ERROR_RETURN ((LM_ERROR,
37 "be_visitor_array_cs::"
38 "visit_array - "
39 "Bad base type\n"),
40 -1);
43 // To hold the full and local.
44 char fname [NAMEBUFSIZE];
45 char lname [NAMEBUFSIZE];
46 ACE_OS::memset (fname,
47 '\0',
48 NAMEBUFSIZE);
49 ACE_OS::memset (lname,
50 '\0',
51 NAMEBUFSIZE);
53 if (this->ctx_->tdef ())
55 // Typedefed node.
56 ACE_OS::sprintf (fname, "%s",
57 node->full_name ());
58 ACE_OS::sprintf (lname, "%s",
59 node->local_name ()->get_string ());
61 else
63 // For anonymous arrays ...
64 // we have to generate a name for us that has an underscope prepended to
65 // our local name. This needs to be inserted after the parents's name.
66 if (node->is_nested ())
68 be_decl *parent =
69 dynamic_cast<be_scope*> (node->defined_in ())->decl ();
70 ACE_OS::sprintf (fname,
71 "%s::_%s",
72 parent->full_name (),
73 node->local_name ()->get_string ());
74 ACE_OS::sprintf (lname,
75 "_%s",
76 node->local_name ()->get_string ());
78 else
80 ACE_OS::sprintf (fname,
81 "_%s",
82 node->full_name ());
83 ACE_OS::sprintf (lname,
84 "_%s",
85 node->local_name ()->get_string ());
89 TAO_INSERT_COMMENT (os);
91 // dup method.
92 *os << fname << "_slice *" << be_nl
93 << fname << "_dup (const " << fname
94 << "_slice *_tao_src_array)" << be_nl;
95 *os << "{" << be_idt_nl;
96 *os << fname << "_slice *_tao_dup_array = "
97 << fname << "_alloc ();" << be_nl << be_nl;
98 *os << "if (_tao_dup_array)" << be_idt_nl
99 << "{" << be_idt_nl;
100 *os << fname << "_copy (_tao_dup_array, _tao_src_array);" << be_uidt_nl
101 << "}" << be_uidt_nl << be_nl;
102 *os << "return _tao_dup_array;" << be_uidt_nl;
103 *os << "}" << be_nl_2;
105 // alloc method.
106 *os << fname << "_slice *" << be_nl;
107 *os << fname << "_alloc ()" << be_nl;
108 *os << "{" << be_idt_nl;
109 *os << fname << "_slice *retval {};" << be_nl;
110 *os << "ACE_NEW_RETURN (retval, ";
112 if (bt->accept (this) == -1)
114 ACE_ERROR_RETURN ((LM_ERROR,
115 "be_visitor_array_cs::"
116 "visit_array - "
117 "base type decl failed\n"),
118 -1);
121 if (node->gen_dimensions (os) == -1)
123 ACE_ERROR_RETURN ((LM_ERROR,
124 "(%N:%l) be_visitor_array_cs::"
125 "visit_array - "
126 "dimensions codegen failed\n"),
127 -1);
130 *os << ", nullptr);" << be_nl;
131 *os << "return retval;" << be_uidt_nl;
132 *os << "}" << be_nl_2;
134 // free method.
135 *os << "void" << be_nl
136 << fname << "_free (" << fname << "_slice *_tao_slice)"
137 << be_nl;
138 *os << "{" << be_idt_nl;
139 *os << "delete [] _tao_slice;" << be_uidt_nl;
140 *os << "}" << be_nl_2;
142 // copy method.
143 *os << "void" << be_nl;
144 *os << fname << "_copy (" << be_idt << be_idt_nl
145 << fname << "_slice * _tao_to," << be_nl
146 << "const " << fname << "_slice *_tao_from)" << be_uidt
147 << be_uidt_nl;
148 *os << "{" << be_idt_nl;
149 *os << "// Copy each individual element." << be_nl;
151 ACE_CDR::ULong ndims = node->n_dims ();
153 // Generate nested loops for as many dimensions as there are.
154 for (i = 0; i < ndims; ++i)
156 // Retrieve the ith dimension value.
157 AST_Expression *expr = node->dims ()[i];
159 if ((expr == nullptr) || ((expr != nullptr) && (expr->ev () == nullptr)))
161 ACE_ERROR_RETURN ((LM_ERROR,
162 "(%N:%l) be_visitor_array_cs::"
163 "visit_array - "
164 "bad array dimension\n"),
165 -1);
168 if (expr->ev ()->et == AST_Expression::EV_ulong)
170 // Generate a loop for each dimension.
171 *os << "for (::CORBA::ULong i" << i << " = 0; i" << i << " < "
172 << expr->ev ()->u.ulval << "; ++i" << i << ")" << be_idt_nl
173 << "{" << be_idt_nl;
175 else
177 ACE_ERROR_RETURN ((LM_ERROR,
178 "(%N:%l) be_visitor_array_cs::"
179 "visit_array - "
180 "bad array dimension value\n"),
181 -1);
185 // Now generate code such that every element of the array gets assigned
186 // inside the innermost level of the nested loops generated above.
187 be_array *primitive_type = nullptr;
189 if (bt->node_type () == AST_Decl::NT_typedef)
191 // Base type of the array node is a typedef. We need to make sure that
192 // this typedef is not to another array type. If it is, then we cannot
193 // assign an array to another. We will have to invoke the underlying
194 // array type's copy method for every array dimension.
196 // There may be more than one level of typedef.
197 be_type *tmp = bt;
199 while (tmp->node_type () == AST_Decl::NT_typedef)
201 be_typedef *tdef = dynamic_cast<be_typedef*> (tmp);
202 tmp = dynamic_cast<be_type*> (tdef->base_type ());
205 primitive_type = dynamic_cast<be_array*> (tmp);
208 if (primitive_type != nullptr)
210 // The base type is a typedef to another array type, so
211 // we use the base type's copy method.
212 *os << "// call the underlying _copy" << be_nl;
214 if (bt->accept (this) == -1)
216 ACE_ERROR_RETURN ((LM_ERROR,
217 "be_visitor_array_cs::"
218 "visit_array - "
219 "base type decl failed\n"),
220 -1);
223 *os << "_copy (_tao_to";
225 for (i = 0; i < ndims; ++i)
227 *os << "[i" << i << "]";
230 *os << ", ";
231 *os << "_tao_from";
233 for (i = 0; i < ndims; ++i)
235 *os << "[i" << i << "]";
238 *os << ");";
240 else
242 // The base type is not a typedef to possibly another array type. In
243 // such a case, assign each element.
245 *os << "_tao_to";
247 for (i = 0; i < ndims; ++i)
249 *os << "[i" << i << "]";
252 *os << " = ";
253 *os << "_tao_from";
255 for (i = 0; i < ndims; ++i)
257 *os << "[i" << i << "]";
260 *os << ";";
263 for (i = 0; i < ndims; ++i)
265 // Add closing braces as many times as the number of dimensions.
266 *os << be_uidt_nl << "}" << be_uidt;
269 *os << be_uidt_nl << "}";
271 AST_Decl::NodeType nt = bt->node_type ();
273 // If we contain an anonymous sequence,
274 // generate code for the sequence here.
275 if (nt == AST_Decl::NT_sequence)
277 if (this->gen_anonymous_base_type (bt,
278 TAO_CodeGen::TAO_ROOT_CS)
279 == -1)
281 ACE_ERROR_RETURN ((LM_ERROR,
282 "(%N:%l) be_visitor_array_cs::"
283 "visit_array - "
284 "gen_anonymous_base_type failed\n"),
285 -1);
289 // If the member's element type
290 // is a declaration (not a reference), we must generate code for
291 // the declaration.
292 if (this->ctx_->alias () == nullptr // Not a typedef.
293 && bt->is_child (this->ctx_->scope ()->decl ()))
295 int status = 0;
296 be_visitor_context ctx (*this->ctx_);
298 switch (nt)
300 case AST_Decl::NT_enum:
302 be_visitor_enum_cs ec_visitor (&ctx);
303 status = bt->accept (&ec_visitor);
304 break;
306 case AST_Decl::NT_struct:
308 be_visitor_structure_cs sc_visitor (&ctx);
309 status = bt->accept (&sc_visitor);
310 break;
312 case AST_Decl::NT_union:
314 be_visitor_union_cs uc_visitor (&ctx);
315 status = bt->accept (&uc_visitor);
316 break;
318 default:
319 break;
322 if (status == -1)
324 ACE_ERROR_RETURN ((LM_ERROR,
325 "(%N:%l) be_visitor_array_ch::"
326 "visit_array - "
327 "array base type codegen failed\n"),
328 -1);
332 node->cli_stub_gen (true);
333 return 0;