2 #include "orbsvcs/Log_Macros.h"
4 #include "ast_expression.h"
6 #include "ast_union_branch.h"
7 #include "ast_union_label.h"
8 #include "utl_identifier.h"
10 #include "ifr_adding_visitor_union.h"
11 #include "ifr_adding_visitor_structure.h"
13 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
16 ifr_adding_visitor_union::ifr_adding_visitor_union (AST_Decl
*scope
)
17 : ifr_adding_visitor (scope
)
21 ifr_adding_visitor_union::~ifr_adding_visitor_union (void)
25 // Specialized visit_scope method for unions only.
27 ifr_adding_visitor_union::visit_scope (UTL_Scope
*node
)
29 // If the union has members that are scopes but not unions,
30 // the regular visit_scope method should be called instead.
31 if (node
->scope_node_type () != AST_Decl::NT_union
)
33 return ifr_adding_visitor::visit_scope (node
);
36 AST_Union
*u
= dynamic_cast<AST_Union
*> (node
);
38 CORBA::ULong
const nfields
= static_cast<CORBA::ULong
> (u
->nfields ());
40 this->members_
.length (nfields
);
44 // Index into members_.
45 CORBA::ULong index
= 0;
50 for (CORBA::ULong i
= 0; i
< nfields
; ++i
)
52 if (u
->field (f
, i
) != 0)
54 ORBSVCS_ERROR_RETURN ((
56 ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
57 ACE_TEXT ("visit_scope -")
58 ACE_TEXT (" field node access failed\n")
64 AST_Type
*ft
= (*f
)->field_type ();
66 bool defined_here
= ft
->is_child (this->scope_
);
68 // If the union member is defined in the union, we have to
69 // do some visiting - otherwise we can just look up the entry.
72 if (ft
->node_type () == AST_Decl::NT_union
)
74 // Since the enclosing scope hasn't been created yet,
75 // we make a special visitor to create this member
76 // at global scope and move it into the union later.
77 ifr_adding_visitor_union
visitor (ft
);
79 if (ft
->ast_accept (&visitor
) == -1)
81 ORBSVCS_ERROR_RETURN ((
83 ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
84 ACE_TEXT ("visit_scope -")
85 ACE_TEXT (" failed to accept visitor\n")),
90 CORBA::IDLType::_duplicate (visitor
.ir_current ());
94 if (ft
->ast_accept (this) == -1)
96 ORBSVCS_ERROR_RETURN ((
98 ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
99 ACE_TEXT ("visit_scope -")
100 ACE_TEXT (" failed to accept visitor\n")),
107 // Updates ir_current_.
108 this->get_referenced_type (ft
);
111 // Get the case label(s).
113 AST_UnionLabel
*case_label
= 0;
114 AST_UnionBranch
*ub
= dynamic_cast<AST_UnionBranch
*> (*f
);
115 unsigned long len
= ub
->label_list_length ();
117 // If there are multiple case labels, we will have an element
118 // in the UnionMemberSeq for each label, not just for each member,
119 // so the list length and the loop terminator must both be
120 // increased accordingly.
123 this->members_
.length (this->members_
.length () + len
- 1);
126 for (unsigned long j
= 0; j
< len
; ++j
)
128 case_label
= ub
->label (j
);
130 // Is this a regular label or default label?
131 if (case_label
->label_kind () == AST_UnionLabel::UL_label
)
133 AST_Expression::AST_ExprValue
*ev
=
134 case_label
->label_val ()->ev ();
136 // If the discriminator is an enum, we can't just insert
137 // a ulong into the Any member of struct UnionMember.
138 if (u
->disc_type ()->node_type () == AST_Decl::NT_enum
)
141 cdr
.write_ulong (ev
->u
.ulval
);
142 TAO_InputCDR
in_cdr (cdr
);
143 TAO::Unknown_IDL_Type
*unk
= 0;
145 TAO::Unknown_IDL_Type (
146 this->disc_tc_
.in (),
149 this->members_
[index
].label
.replace (unk
);
154 this->members_
[index
].label
);
157 else // Default case label.
159 this->members_
[index
].label
<<= CORBA::Any::from_octet (0);
162 this->members_
[index
].name
=
163 CORBA::string_dup ((*f
)->local_name ()->get_string ());
165 // IfR method create_union does not use this - it just needs
166 // to be non-zero for marshaling.
167 this->members_
[index
].type
=
168 CORBA::TypeCode::_duplicate (CORBA::_tc_void
);
170 this->members_
[index
++].type_def
=
171 CORBA::IDLType::_duplicate (this->ir_current_
.in ());
175 catch (const CORBA::Exception
& ex
)
177 ex
._tao_print_exception (
179 "ifr_adding_visitor_union::visit_scope"));
188 ifr_adding_visitor_union::visit_structure (AST_Structure
*node
)
192 // Is this struct already in the respository?
193 CORBA::Contained_var prev_def
=
194 be_global
->repository ()->lookup_id (node
->repoID ());
196 // If not, create a new entry.
197 if (CORBA::is_nil (prev_def
.in ()))
199 ifr_adding_visitor_structure
visitor (node
);
200 int retval
= visitor
.visit_structure (node
);
204 // Get the result of the visit.
206 CORBA::IDLType::_duplicate (visitor
.ir_current ());
213 // If the line below is true, we are clobbering a previous
214 // entry (from another IDL file) of another type. In that
215 // case we do what other ORB vendors do, and destroy the
216 // original entry, create the new one, and let the user beware.
217 if (!node
->ifr_added ())
219 prev_def
->destroy ();
221 // This call will take the other branch.
222 return this->visit_structure (node
);
226 CORBA::IDLType::_narrow (prev_def
.in ());
229 catch (const CORBA::Exception
& ex
)
231 ex
._tao_print_exception (
233 "ifr_adding_visitor_union::visit_structure"));
242 ifr_adding_visitor_union::visit_enum (AST_Enum
*node
)
246 // Is this enum already in the respository?
247 CORBA::Contained_var prev_def
=
248 be_global
->repository ()->lookup_id (node
->repoID ());
250 // If not, create a new entry.
251 if (CORBA::is_nil (prev_def
.in ()))
253 CORBA::ULong member_count
=
254 static_cast<CORBA::ULong
> (node
->member_count ());
256 CORBA::EnumMemberSeq
members (member_count
);
257 members
.length (member_count
);
259 UTL_ScopedName
*member_name
= 0;
261 // Get a list of the member names.
262 for (CORBA::ULong i
= 0; i
< member_count
; ++i
)
264 member_name
= node
->value_to_name (i
);
268 member_name
->last_component ()->get_string ());
272 be_global
->repository ()->create_enum (
274 node
->local_name ()->get_string (),
279 node
->ifr_added (true);
283 // If the line below is true, we are clobbering a previous
284 // entry (from another IDL file) of another type. In that
285 // case we do what other ORB vendors do, and destroy the
286 // original entry, create the new one, and let the user beware.
287 if (!node
->ifr_added ())
289 prev_def
->destroy ();
291 // This call will take the other branch.
292 return this->visit_enum (node
);
296 CORBA::IDLType::_narrow (prev_def
.in ());
299 catch (const CORBA::Exception
& ex
)
301 ex
._tao_print_exception (
303 "ifr_adding_visitor_union::visit_enum"));
312 ifr_adding_visitor_union::visit_union (AST_Union
*node
)
316 // This will put the discriminator in ir_current_.
317 if (node
->disc_type ()->ast_accept (this) == -1)
319 ORBSVCS_ERROR_RETURN ((
321 ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
322 ACE_TEXT ("visit_union -")
323 ACE_TEXT (" visit of discriminator failed\n")),
327 this->disc_tc_
= this->ir_current_
->type ();
329 CORBA::UnionDef_var union_def
;
330 CORBA::Contained_var prev_def
=
331 be_global
->repository ()->lookup_id (node
->repoID ());
333 if (CORBA::is_nil (prev_def
.in ()))
335 CORBA::UnionMemberSeq dummyMembers
;
336 dummyMembers
.length (0);
337 CORBA::Container_ptr current_scope
= CORBA::Container::_nil ();
339 if (be_global
->ifr_scopes ().top (current_scope
) != 0)
341 ORBSVCS_ERROR_RETURN ((
343 ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
344 ACE_TEXT ("visit_union -")
345 ACE_TEXT (" scope stack is empty\n")),
349 // First create the named union without any members.
351 current_scope
->create_union (
353 node
->local_name ()->get_string (),
355 this->ir_current_
.in (),
359 if (be_global
->ifr_scopes ().push (union_def
.in ()) != 0)
361 ORBSVCS_ERROR_RETURN ((
363 ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
364 ACE_TEXT ("visit_union -")
365 ACE_TEXT (" scope push failed\n")
371 // Then add the real union members (which corrupts ir_current_).
372 if (this->add_members (node
, union_def
.in ()) == -1)
374 ORBSVCS_ERROR_RETURN ((
376 ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::visit_union -")
377 ACE_TEXT (" visit_scope failed\n")),
381 this->ir_current_
= CORBA::IDLType::_narrow (union_def
.in ());
383 CORBA::Container_ptr used_scope
=
384 CORBA::Container::_nil ();
386 // Pop the new IR object back off the scope stack.
387 if (be_global
->ifr_scopes ().pop (used_scope
) != 0)
389 ORBSVCS_ERROR_RETURN ((
391 ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
392 ACE_TEXT ("visit_union -")
393 ACE_TEXT (" scope pop failed\n")
398 } // if (CORBA::is_nil (...))
401 // We are seeing the full definition of a forward
402 // declaration - just add the members so repo
403 // entries referencing the UnionDef will stay valid.
404 // Also we know node->ifr_fwd_added_ is true.
405 union_def
= CORBA::UnionDef::_narrow (prev_def
.in ());
406 union_def
->discriminator_type_def (this->ir_current_
.in ());
408 if (be_global
->ifr_scopes ().push (union_def
.in ()) != 0)
410 ORBSVCS_ERROR_RETURN ((
412 ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
413 ACE_TEXT ("visit_union -")
414 ACE_TEXT (" scope push failed\n")
420 if (this->add_members (node
, union_def
.in ()) == -1)
422 ORBSVCS_ERROR_RETURN ((
424 ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
425 ACE_TEXT ("visit_union -")
426 ACE_TEXT (" visit_scope failed\n")),
430 this->ir_current_
= CORBA::IDLType::_narrow (prev_def
.in ());
432 CORBA::Container_ptr used_scope
=
433 CORBA::Container::_nil ();
435 // Pop the new IR object back off the scope stack.
436 if (be_global
->ifr_scopes ().pop (used_scope
) != 0)
438 ORBSVCS_ERROR_RETURN ((
440 ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
441 ACE_TEXT ("visit_union -")
442 ACE_TEXT (" scope pop failed\n")
449 catch (const CORBA::Exception
& ex
)
451 ex
._tao_print_exception (
453 "ifr_adding_visitor_union::visit_union"));
462 ifr_adding_visitor_union::ir_current (void) const
464 return this->ir_current_
.in ();
468 ifr_adding_visitor_union::add_members (AST_Union
*node
,
469 CORBA::UnionDef_ptr union_def
)
471 if (this->visit_scope (node
) == -1)
473 ORBSVCS_ERROR_RETURN ((
475 ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::visit_union -")
476 ACE_TEXT (" visit_scope failed\n")),
480 // Correct ir_current_ and move the real union members into the union.
481 this->ir_current_
= CORBA::UnionDef::_duplicate (union_def
);
482 union_def
->members (this->members_
);
484 node
->ifr_added (true);