Changes to attempt to silence bcc64x
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_union / union_cs.cpp
blobc0ab0850bbf56a957b249753fa531554ab98badd
2 //=============================================================================
3 /**
4 * @file union_cs.cpp
6 * Visitor generating code for Unions in the client stubs
8 * @author Aniruddha Gokhale
9 */
10 //=============================================================================
12 #include "union.h"
14 be_visitor_union_cs::be_visitor_union_cs (be_visitor_context *ctx)
15 : be_visitor_union (ctx)
19 be_visitor_union_cs::~be_visitor_union_cs ()
23 // Visit the Union_cs node and its scope.
24 int be_visitor_union_cs::visit_union (be_union *node)
26 if (node->cli_stub_gen () || node->imported ())
28 return 0;
31 TAO_OutStream *os = this->ctx_->stream ();
33 be_visitor_context ctx (*this->ctx_);
34 // The discriminant type may have to be defined here if it was an enum
35 // declaration inside of the union statement. We need to generate its
36 // typecode.
38 be_type *bt = dynamic_cast<be_type*> (node->disc_type ());
40 if (!bt)
42 ACE_ERROR_RETURN ((LM_ERROR,
43 "(%N:%l) be_visitor_union_cs::"
44 "visit_union - "
45 "bad discriminant type\n"), -1);
48 be_visitor_union_discriminant_cs disc_visitor (&ctx);
50 if (bt->accept (&disc_visitor) == -1)
52 ACE_ERROR_RETURN ((LM_ERROR,
53 "(%N:%l) be_visitor_union_cs::"
54 "visit union - "
55 "codegen for discrminant failed\n"),
56 -1);
59 // First generate code for any of the members (if required, e.g.,
60 // anonymous sequences, structs, unions, arrays).
61 this->ctx_->state (TAO_CodeGen::TAO_UNION_PUBLIC_CS);
63 if (this->visit_scope (node) == -1)
65 ACE_ERROR_RETURN ((LM_ERROR,
66 "(%N:%l) be_visitor_union_cs"
67 "visit_union - "
68 "codegen for scope failed\n"),
69 -1);
72 // Now generate the operations on the union such as the copy constructor
73 // and the assignment operator.
75 TAO_INSERT_COMMENT (os);
77 // Generate the copy constructor and the assignment operator here.
78 *os << be_nl_2
79 << node->name () << "::" << node->local_name () << " ()" << be_nl
80 << "{" << be_idt_nl
81 << "ACE_OS::memset (&this->u_, 0, sizeof (this->u_));" << be_nl;
83 // The default constructor must initialize the discriminator
84 // to the first case label value found in the union declaration
85 // so that, if the uninitialized union is inserted into an Any,
86 // the Any destructor's call to deep_free() will work properly.
88 *os << "this->disc_ = ";
90 UTL_ScopeActiveIterator si (node, UTL_Scope::IK_decls);
91 be_union_branch *ub = nullptr;
93 // In case we have some bogus enum values from an enum declared
94 // in our scope.
95 while (ub == nullptr)
97 // Just get the union's first member.
98 AST_Decl *d = si.item ();
100 ub = dynamic_cast<be_union_branch*> (d);
101 si.next ();
104 // Get the first label in its list.
105 AST_UnionLabel *ul = ub->label (0);
107 AST_Union::DefaultValue dv;
108 // This can indicate an error in the return value, but it is
109 // caught elsewhere.
110 (void) node->default_value (dv);
112 bool test = dv.computed_ == 0
113 && ul->label_kind () == AST_UnionLabel::UL_label;
115 if (test)
117 ub->gen_label_value (os);
119 else
121 ub->gen_default_label_value (os, node);
124 *os << ";";
126 if (dv.computed_ == 0)
128 *os << be_nl;
129 be_visitor_union_branch_public_constructor_cs const_visitor (this->ctx_);
130 if (ub->accept (&const_visitor) == -1)
132 ACE_ERROR_RETURN ((LM_ERROR,
133 "(%N:%l) be_visitor_union_cs::"
134 "visit union - "
135 "codegen for constructor failed\n"),
136 -1);
140 *os << be_uidt_nl << "}" << be_nl_2;
142 this->ctx_->state (TAO_CodeGen::TAO_UNION_PUBLIC_ASSIGN_CS);
144 // So we know we are generating the copy constructor.
145 this->ctx_->sub_state (TAO_CodeGen::TAO_UNION_COPY_CONSTRUCTOR);
147 const bool boolDisc = node->udisc_type() == AST_Expression::EV_bool;
149 *os << node->name () << "::" << node->local_name ()
150 << " (const ::" << node->name () << " &u)"
151 << be_nl;
152 *os << "{" << be_idt_nl;
153 *os << "this->disc_ = u.disc_;" << be_nl;
155 if (!boolDisc)
157 *os << "switch (this->disc_)" << be_nl;
158 *os << "{" << be_idt;
161 if (this->visit_scope (node) == -1)
163 ACE_ERROR_RETURN ((LM_ERROR,
164 "(%N:%l) be_visitor_union_cs"
165 "visit_union - "
166 "codegen for copy ctor failed\n"),
167 -1);
170 // If there is no explicit default case, but there
171 // is an implicit one, and the discriminant is an enum,
172 // we need this to avert warnings in some compilers that
173 // not all case values are included. If there is no
174 // implicit default case, or the discriminator is not
175 // an enum, this does no harm.
176 if (!boolDisc && node->gen_empty_default_label ())
178 *os << be_nl
179 << "default:" << be_nl
180 << "break;";
183 if (!boolDisc)
185 *os << be_uidt_nl << "}";
188 *os << be_uidt_nl << "}" << be_nl_2;
190 *os << node->name () << "::~" << node->local_name ()
191 << " ()" << be_nl
192 << "{" << be_idt_nl
193 << "// Finalize." << be_nl
194 << "this->_reset ();" << be_uidt_nl
195 << "}" << be_nl_2;
197 if (be_global->any_support ())
199 *os << "void "
200 << node->name ()
201 << "::_tao_any_destructor (void *_tao_void_pointer)" << be_nl
202 << "{" << be_idt_nl
203 << node->local_name () << " *tmp =" << be_idt_nl
204 << "static_cast<"
205 << node->local_name () << " *> (_tao_void_pointer);" << be_uidt_nl
206 << "delete tmp;" << be_uidt_nl
207 << "}" << be_nl_2;
210 this->ctx_->state (TAO_CodeGen::TAO_UNION_PUBLIC_ASSIGN_CS);
212 // Reset this for generating the assignment operator.
213 this->ctx_->sub_state (TAO_CodeGen::TAO_SUB_STATE_UNKNOWN);
215 // Assignment operator.
216 *os << node->name () << " &" << be_nl;
217 *os << node->name () << "::operator= (const ::"
218 << node->name () << " &u)" << be_nl;
219 *os << "{" << be_idt_nl;
220 // First check for self-assignment.
221 *os << "if (std::addressof(u) == this)" << be_idt_nl
222 << "{" << be_idt_nl
223 << "return *this;" << be_uidt_nl
224 << "}" << be_uidt_nl << be_nl;
225 // Reset and set the discriminant.
226 *os << "this->_reset ();" << be_nl;
227 *os << "this->disc_ = u.disc_;" << be_nl_2;
228 // now switch based on the disc value
229 if (!boolDisc)
231 *os << "switch (this->disc_)" << be_nl;
232 *os << "{" << be_idt;
235 if (this->visit_scope (node) == -1)
237 ACE_ERROR_RETURN ((LM_ERROR,
238 "(%N:%l) be_visitor_union_cs"
239 "visit_union - "
240 "codegen for assign op failed\n"),
241 -1);
244 // If there is no explicit default case, but there
245 // is an implicit one, and the discriminant is an enum,
246 // we need this to avert warnings in some compilers that
247 // not all case values are included. If there is no
248 // implicit default case, or the discriminator is not
249 // an enum, this does no harm.
250 if (!boolDisc && node->gen_empty_default_label ())
252 *os << be_nl
253 << "default:" << be_nl
254 << "break;";
257 if (!boolDisc)
259 *os << be_uidt_nl << "}" << be_nl;
262 *os << be_nl << "return *this;" << be_uidt_nl;
263 *os << "}" << be_nl_2;
265 // The reset method.
266 this->ctx_->state (TAO_CodeGen::TAO_UNION_PUBLIC_RESET_CS);
268 *os << "/// Reset method to reset old values of a union." << be_nl;
269 *os << "void " << node->name () << "::_reset ()" << be_nl;
270 *os << "{" << be_idt_nl;
272 if (!boolDisc)
274 *os << "switch (this->disc_)" << be_nl;
275 *os << "{" << be_idt_nl;
278 if (this->visit_scope (node) == -1)
280 ACE_ERROR_RETURN ((LM_ERROR,
281 "(%N:%l) be_visitor_union_cs"
282 "visit_union - "
283 "codegen for reset failed\n"),
284 -1);
287 // If there is no explicit default case, but there
288 // is an implicit one, and the discriminant is an enum,
289 // we need this to avert warnings in some compilers that
290 // not all case values are included. If there is no
291 // implicit default case, or the discriminator is not
292 // an enum, this does no harm.
293 if (!boolDisc && node->gen_empty_default_label ())
295 *os << be_nl
296 << "default:" << be_nl
297 << "break;";
300 if (!boolDisc)
302 *os << be_uidt_nl << "}";
305 *os << be_uidt_nl << "}";
307 if (be_global->tc_support ())
309 ctx = *this->ctx_;
310 // ctx.sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE);
311 TAO::be_visitor_union_typecode tc_visitor (&ctx);
313 if (tc_visitor.visit_union (node) == -1)
315 ACE_ERROR_RETURN ((LM_ERROR,
316 "(%N:%l) be_visitor_union_cs::"
317 "visit_union - "
318 "TypeCode definition failed\n"),
319 -1);
323 node->cli_stub_gen (true);
324 return 0;