Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / TAO_IDL / be / be_union.cpp
blob7073184e51f54067be0ae1bbb15611f76ab38b83
2 //=============================================================================
3 /**
4 * @file be_union.cpp
6 * Extension of class AST_Union that provides additional means for C++
7 * mapping.
9 * @author Copyright 1994-1995 by Sun Microsystems
10 * @author Inc. and Aniruddha Gokhale
12 //=============================================================================
14 #include "be_union.h"
15 #include "be_union_branch.h"
16 #include "be_union_label.h"
17 #include "be_visitor.h"
18 #include "be_codegen.h"
19 #include "be_helper.h"
20 #include "be_extern.h"
22 #include "ast_union_branch.h"
23 #include "ast_enum.h"
24 #include "utl_identifier.h"
25 #include "idl_defines.h"
26 #include "global_extern.h"
28 be_union::be_union (AST_ConcreteType *dt,
29 UTL_ScopedName *n,
30 bool local,
31 bool abstract)
32 : COMMON_Base (local,
33 abstract),
34 AST_Decl (AST_Decl::NT_union,
35 n),
36 AST_Type (AST_Decl::NT_union,
37 n),
38 AST_ConcreteType (AST_Decl::NT_union,
39 n),
40 UTL_Scope (AST_Decl::NT_union),
41 AST_Structure (AST_Decl::NT_union,
43 local,
44 abstract),
45 AST_Union (dt,
47 local,
48 abstract),
49 be_scope (AST_Decl::NT_union),
50 be_decl (AST_Decl::NT_union,
51 n),
52 be_type (AST_Decl::NT_union,
55 // Always the case.
56 this->has_constructor (true);
58 if (!this->imported ())
60 idl_global->aggregate_seen_ = true;
62 idl_global->union_seen_ = true;
66 void
67 be_union::redefine (AST_Structure *from)
69 be_union *bu = dynamic_cast<be_union*> (from);
70 this->common_varout_gen_ = bu->common_varout_gen_;
71 AST_Union::redefine (from);
74 bool
75 be_union::has_duplicate_case_labels (void)
77 for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls);
78 !si.is_done ();
79 si.next ())
81 AST_Decl *d = si.item ();
82 AST_UnionBranch *ub =
83 dynamic_cast<AST_UnionBranch*> (d);
85 if (ub->label_list_length () > 1)
87 return true;
91 return false;
94 void
95 be_union::gen_ostream_operator (TAO_OutStream *os,
96 bool /*use_underscore*/)
98 *os << be_nl
99 << "std::ostream& operator<< (" << be_idt << be_idt_nl
100 << "std::ostream &strm," << be_nl
101 << "const " << this->name () << " &_tao_union" << be_uidt_nl
102 << ")" << be_uidt_nl
103 << "{" << be_idt_nl
104 << "strm << \"" << this->name () << "(\";" << be_nl_2
105 << "switch (_tao_union._d ())" << be_nl
106 << "{" << be_idt;
108 for (long i = 0; i < this->pd_decls_used; ++i)
110 be_union_branch *ub =
111 dynamic_cast<be_union_branch*> (this->pd_decls[i]);
113 // We don't want any decls, just members.
114 if (ub == 0)
116 continue;
119 *os << be_nl;
121 unsigned long ll_len = ub->label_list_length ();
123 for (unsigned long j = 0; j < ll_len; ++j)
125 // Check if we are printing the default case.
126 if (ub->label (j)->label_kind () == AST_UnionLabel::UL_default)
128 *os << "default:";
130 else
132 *os << "case ";
134 ub->gen_label_value (os, j);
136 *os << ":";
139 if (j == ll_len - 1)
141 *os << be_idt_nl;
143 else
145 *os << be_nl;
149 ACE_CString instance_name ("_tao_union.");
150 instance_name += ub->local_name ()->get_string ();
152 *os << "strm << ";
154 be_type *ub_ft = dynamic_cast<be_type*> (ub->field_type ());
155 AST_Decl::NodeType ub_nt = ub_ft->node_type ();
156 // catch anonymous Array member types
157 bool ub_use_underscore = ub_nt == AST_Decl::NT_array;
159 ub->gen_member_ostream_operator (os,
160 instance_name.c_str (),
161 ub_use_underscore,
162 true);
164 *os << ";" << be_nl
165 << "break;" << be_uidt;
168 // Some compilers complain unless this is present, but only
169 // if not all values are covered in case statements.
170 if (this->gen_empty_default_label ())
172 *os << be_nl
173 << "default:" << be_idt_nl
174 << "break;" << be_uidt;
177 *os << be_uidt_nl
178 << "}" << be_nl_2
179 << "return strm << \")\";" << be_uidt_nl
180 << "}" << be_nl;
183 void
184 be_union::destroy (void)
186 // Call the destroy methods of our base classes.
187 this->be_scope::destroy ();
188 this->be_type::destroy ();
189 this->AST_Union::destroy ();
193 // Visitor method.
195 be_union::accept (be_visitor *visitor)
197 return visitor->visit_union (this);
200 bool
201 be_union::gen_empty_default_label (void)
203 // A non-empty explicit default label will be generated.
204 if (this->default_index () != -1)
206 return false;
209 AST_ConcreteType *disc = this->disc_type ();
210 if (disc == 0)
212 return true; // In reality this is an error.
215 AST_Decl::NodeType nt = disc->node_type ();
216 ACE_UINT64 n_labels = this->nlabels ();
218 if (nt == AST_Decl::NT_enum)
220 // Enums in CORBA are always 32bits in size, so unless
221 // there are that many enum labels in the set, it is
222 // incomplete (reguardless as to the actual member_count).
223 return (n_labels <= ACE_UINT32_MAX);
226 AST_PredefinedType *pdt = dynamic_cast<AST_PredefinedType*> (disc);
227 if (pdt == 0)
229 return true; // In reality this is an error.
232 switch (pdt->pt ())
234 case AST_PredefinedType::PT_boolean:
235 return (n_labels < 2);
237 case AST_PredefinedType::PT_char:
238 return (n_labels <= ACE_OCTET_MAX);
240 case AST_PredefinedType::PT_short:
241 case AST_PredefinedType::PT_ushort:
242 return (n_labels <= ACE_UINT16_MAX);
244 case AST_PredefinedType::PT_long:
245 case AST_PredefinedType::PT_ulong:
246 return (n_labels <= ACE_UINT32_MAX);
248 case AST_PredefinedType::PT_longlong:
249 case AST_PredefinedType::PT_ulonglong:
250 // We would wrap to 0 here - we are using a 64 bit count
251 // this case is so marginal as to always be incomplete.
252 return true;
254 // Keep fussy compilers happy.
255 default:
256 break;
259 return true;
262 AST_UnionBranch *
263 be_union::be_add_union_branch (AST_UnionBranch *b)
265 return this->fe_add_union_branch (b);
268 ACE_UINT64
269 be_union::nlabels (void)
271 ACE_UINT64 retval = 0;
273 for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls);
274 !si.is_done ();
275 si.next ())
277 AST_Decl *d = si.item ();
278 AST_UnionBranch *ub =
279 dynamic_cast<AST_UnionBranch*> (d);
281 if (ub != 0)
283 retval += ub->label_list_length ();
287 return retval;
292 IMPL_NARROW_FROM_DECL (be_union)
293 IMPL_NARROW_FROM_SCOPE (be_union)