2 //=============================================================================
6 * Visitor for code generation of Arrays in the client stubs
8 * @author Aniruddha Gokhale
10 //=============================================================================
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 ()))
27 TAO_OutStream
*os
= this->ctx_
->stream ();
29 this->ctx_
->node (node
);
32 be_type
*bt
= dynamic_cast<be_type
*> (node
->base_type ());
36 ACE_ERROR_RETURN ((LM_ERROR
,
37 "be_visitor_array_cs::"
43 // To hold the full and local.
44 char fname
[NAMEBUFSIZE
];
45 char lname
[NAMEBUFSIZE
];
46 ACE_OS::memset (fname
,
49 ACE_OS::memset (lname
,
53 if (this->ctx_
->tdef ())
56 ACE_OS::sprintf (fname
, "%s",
58 ACE_OS::sprintf (lname
, "%s",
59 node
->local_name ()->get_string ());
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 ())
69 dynamic_cast<be_scope
*> (node
->defined_in ())->decl ();
70 ACE_OS::sprintf (fname
,
73 node
->local_name ()->get_string ());
74 ACE_OS::sprintf (lname
,
76 node
->local_name ()->get_string ());
80 ACE_OS::sprintf (fname
,
83 ACE_OS::sprintf (lname
,
85 node
->local_name ()->get_string ());
89 TAO_INSERT_COMMENT (os
);
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
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
;
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::"
117 "base type decl failed\n"),
121 if (node
->gen_dimensions (os
) == -1)
123 ACE_ERROR_RETURN ((LM_ERROR
,
124 "(%N:%l) be_visitor_array_cs::"
126 "dimensions codegen failed\n"),
130 *os
<< ", nullptr);" << be_nl
;
131 *os
<< "return retval;" << be_uidt_nl
;
132 *os
<< "}" << be_nl_2
;
135 *os
<< "void" << be_nl
136 << fname
<< "_free (" << fname
<< "_slice *_tao_slice)"
138 *os
<< "{" << be_idt_nl
;
139 *os
<< "delete [] _tao_slice;" << be_uidt_nl
;
140 *os
<< "}" << be_nl_2
;
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
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::"
164 "bad array dimension\n"),
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
177 ACE_ERROR_RETURN ((LM_ERROR
,
178 "(%N:%l) be_visitor_array_cs::"
180 "bad array dimension value\n"),
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.
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::"
219 "base type decl failed\n"),
223 *os
<< "_copy (_tao_to";
225 for (i
= 0; i
< ndims
; ++i
)
227 *os
<< "[i" << i
<< "]";
233 for (i
= 0; i
< ndims
; ++i
)
235 *os
<< "[i" << i
<< "]";
242 // The base type is not a typedef to possibly another array type. In
243 // such a case, assign each element.
247 for (i
= 0; i
< ndims
; ++i
)
249 *os
<< "[i" << i
<< "]";
255 for (i
= 0; i
< ndims
; ++i
)
257 *os
<< "[i" << i
<< "]";
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
)
281 ACE_ERROR_RETURN ((LM_ERROR
,
282 "(%N:%l) be_visitor_array_cs::"
284 "gen_anonymous_base_type failed\n"),
289 // If the member's element type
290 // is a declaration (not a reference), we must generate code for
292 if (this->ctx_
->alias () == nullptr // Not a typedef.
293 && bt
->is_child (this->ctx_
->scope ()->decl ()))
296 be_visitor_context
ctx (*this->ctx_
);
300 case AST_Decl::NT_enum
:
302 be_visitor_enum_cs
ec_visitor (&ctx
);
303 status
= bt
->accept (&ec_visitor
);
306 case AST_Decl::NT_struct
:
308 be_visitor_structure_cs
sc_visitor (&ctx
);
309 status
= bt
->accept (&sc_visitor
);
312 case AST_Decl::NT_union
:
314 be_visitor_union_cs
uc_visitor (&ctx
);
315 status
= bt
->accept (&uc_visitor
);
324 ACE_ERROR_RETURN ((LM_ERROR
,
325 "(%N:%l) be_visitor_array_ch::"
327 "array base type codegen failed\n"),
332 node
->cli_stub_gen (true);