Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / TAO_IDL / ast / ast_union.cpp
blob4d803e31c6a0b3722f6c860d213fe5acb3820d7c
1 /*
3 COPYRIGHT
5 Copyright 1992, 1993, 1994 Sun Microsystems, Inc. Printed in the United
6 States of America. All Rights Reserved.
8 This product is protected by copyright and distributed under the following
9 license restricting its use.
11 The Interface Definition Language Compiler Front End (CFE) is made
12 available for your use provided that you include this license and copyright
13 notice on all media and documentation and the software program in which
14 this product is incorporated in whole or part. You may copy and extend
15 functionality (but may not remove functionality) of the Interface
16 Definition Language CFE without charge, but you are not authorized to
17 license or distribute it to anyone else except as part of a product or
18 program developed by you or with the express written consent of Sun
19 Microsystems, Inc. ("Sun").
21 The names of Sun Microsystems, Inc. and any of its subsidiaries or
22 affiliates may not be used in advertising or publicity pertaining to
23 distribution of Interface Definition Language CFE as permitted herein.
25 This license is effective until terminated by Sun for failure to comply
26 with this license. Upon termination, you shall destroy or return all code
27 and documentation for the Interface Definition Language CFE.
29 INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED AS IS WITH NO WARRANTIES OF
30 ANY KIND INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS
31 FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR ARISING FROM A COURSE OF
32 DEALING, USAGE OR TRADE PRACTICE.
34 INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED WITH NO SUPPORT AND WITHOUT
35 ANY OBLIGATION ON THE PART OF Sun OR ANY OF ITS SUBSIDIARIES OR AFFILIATES
36 TO ASSIST IN ITS USE, CORRECTION, MODIFICATION OR ENHANCEMENT.
38 SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES SHALL HAVE NO LIABILITY WITH
39 RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY
40 INTERFACE DEFINITION LANGUAGE CFE OR ANY PART THEREOF.
42 IN NO EVENT WILL SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES BE LIABLE FOR
43 ANY LOST REVENUE OR PROFITS OR OTHER SPECIAL, INDIRECT AND CONSEQUENTIAL
44 DAMAGES, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
46 Use, duplication, or disclosure by the government is subject to
47 restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
48 Technical Data and Computer Software clause at DFARS 252.227-7013 and FAR
49 52.227-19.
51 Sun, Sun Microsystems and the Sun logo are trademarks or registered
52 trademarks of Sun Microsystems, Inc.
54 SunSoft, Inc.
55 2550 Garcia Avenue
56 Mountain View, California 94043
58 NOTE:
60 SunOS, SunSoft, Sun, Solaris, Sun Microsystems or the Sun logo are
61 trademarks or registered trademarks of Sun Microsystems, Inc.
65 // AST_Union nodes represent IDL union declarations.
66 // AST_Union is a subclass of AST_ConcreteType and of UTL_Scope (the
67 // union branches are managed in a scope).
68 // AST_Union nodes have a discriminator type (a subclass of AST_ConcreteType),
69 // a name (an UTL_ScopedName) and a field denoting the discriminator type if
70 // it is a primitive type (the value of this field is from the union
71 // AST_Expression::ExprType and serves as a cache). This field is used
72 // to compute coercions for labels based on the expected discriminator type.
74 #include "ast_union.h"
75 #include "ast_union_branch.h"
76 #include "ast_union_label.h"
77 #include "ast_field.h"
78 #include "ast_predefined_type.h"
79 #include "ast_enum.h"
80 #include "ast_enum_val.h"
81 #include "ast_typedef.h"
82 #include "ast_visitor.h"
83 #include "utl_err.h"
84 #include "utl_identifier.h"
85 #include "utl_indenter.h"
86 #include "global_extern.h"
87 #include "ast_annotation_appl.h"
89 // FUZZ: disable check_for_streams_include
90 #include "ace/streams.h"
92 AST_Union::AST_Union (AST_ConcreteType *dt,
93 UTL_ScopedName *n,
94 bool local,
95 bool abstract)
96 : COMMON_Base (local,
97 abstract),
98 AST_Decl (AST_Decl::NT_union,
99 n),
100 AST_Type (AST_Decl::NT_union,
102 AST_ConcreteType (AST_Decl::NT_union,
104 UTL_Scope (AST_Decl::NT_union),
105 AST_Structure (n,
106 local,
107 abstract),
108 default_index_ (-2)
110 this->default_value_.computed_ = -2;
112 AST_PredefinedType *pdt = 0;
114 if (dt == 0)
116 this->pd_disc_type = 0;
117 this->pd_udisc_type = AST_Expression::EV_none;
118 return;
121 // If the discriminator type is a predefined type
122 // then install the equivalent coercion target type in
123 // the pd_udisc_type field.
124 if (dt->node_type () == AST_Decl::NT_pre_defined)
126 pdt = dynamic_cast<AST_PredefinedType*> (dt);
128 if (pdt == 0)
130 this->pd_disc_type = 0;
131 this->pd_udisc_type = AST_Expression::EV_none;
132 return;
135 pd_disc_type = dt;
137 switch (pdt->pt ())
139 case AST_PredefinedType::PT_long:
140 this->pd_udisc_type = AST_Expression::EV_long;
141 break;
142 case AST_PredefinedType::PT_ulong:
143 this->pd_udisc_type = AST_Expression::EV_ulong;
144 break;
145 case AST_PredefinedType::PT_longlong:
146 this->pd_udisc_type = AST_Expression::EV_longlong;
147 break;
148 case AST_PredefinedType::PT_ulonglong:
149 this->pd_udisc_type = AST_Expression::EV_ulonglong;
150 break;
151 case AST_PredefinedType::PT_short:
152 this->pd_udisc_type = AST_Expression::EV_short;
153 break;
154 case AST_PredefinedType::PT_ushort:
155 this->pd_udisc_type = AST_Expression::EV_ushort;
156 break;
157 case AST_PredefinedType::PT_int8:
158 this->pd_udisc_type = AST_Expression::EV_int8;
159 break;
160 case AST_PredefinedType::PT_char:
161 this->pd_udisc_type = AST_Expression::EV_char;
162 break;
163 case AST_PredefinedType::PT_wchar:
164 this->pd_udisc_type = AST_Expression::EV_wchar;
165 break;
166 case AST_PredefinedType::PT_uint8:
167 this->pd_udisc_type = AST_Expression::EV_uint8;
168 break;
169 case AST_PredefinedType::PT_octet:
170 this->pd_udisc_type = AST_Expression::EV_octet;
171 break;
172 case AST_PredefinedType::PT_boolean:
173 this->pd_udisc_type = AST_Expression::EV_bool;
174 break;
175 default:
176 this->pd_udisc_type = AST_Expression::EV_none;
177 this->pd_disc_type = 0;
178 break;
181 else if (dt->node_type () == AST_Decl::NT_enum)
183 this->pd_udisc_type = AST_Expression::EV_enum;
184 this->pd_disc_type = dt;
186 else
188 this->pd_udisc_type = AST_Expression::EV_none;
189 this->pd_disc_type = 0;
192 if (this->pd_disc_type == 0)
194 idl_global->err ()->error2 (UTL_Error::EIDL_DISC_TYPE,
195 this,
196 dt);
200 AST_Union::~AST_Union (void)
204 // Public operations.
206 void
207 AST_Union::redefine (AST_Structure *from)
209 AST_Union *u = dynamic_cast<AST_Union*> (from);
211 if (u == 0)
213 idl_global->err ()->redef_error (from->local_name ()->get_string (),
214 this->local_name ()->get_string ());
215 return;
218 // Copy over all the base class members.
219 this->AST_Structure::redefine (from);
221 this->pd_disc_type = u->pd_disc_type;
222 this->pd_udisc_type = u->pd_udisc_type;
223 this->default_index_ = u->default_index_;
224 this->default_value_ = u->default_value_;
227 // Return the default_index.
229 AST_Union::default_index (void)
231 if (this->default_index_ == -2)
233 this->compute_default_index ();
236 return this->default_index_;
239 // Are we or the parameter node involved in any recursion?
240 bool
241 AST_Union::in_recursion (ACE_Unbounded_Queue<AST_Type *> &list)
243 bool self_test = (list.size () == 0);
245 // We should calculate this only once. If it has already been
246 // done, just return it.
247 if (self_test && this->in_recursion_ != -1)
249 return (this->in_recursion_ == 1);
252 if (list.size () > 1)
254 if (match_names (this, list))
256 // We've found ourselves outside of a sequence.
257 // This happens when we are not recursed ourselves but instead
258 // are part of another recursive type
259 return false;
263 list.enqueue_tail(this);
265 // Proceed if the number of members in our scope is greater than 0.
266 if (this->nmembers () > 0)
268 // Initialize an iterator to iterate thru our scope.
269 // Continue until each element is visited.
270 for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls);
271 !si.is_done ();
272 si.next ())
274 AST_UnionBranch *field = dynamic_cast<AST_UnionBranch*> (si.item ());
276 if (field == 0)
277 // This will be an enum value or other legitimate non-field
278 // member - in any case, no recursion.
280 continue;
283 AST_Type *type = field->field_type ();
285 if (type->node_type () == AST_Decl::NT_typedef)
287 AST_Typedef *td = dynamic_cast<AST_Typedef*> (type);
288 type = td->primitive_base_type ();
291 if (type == 0)
293 ACE_ERROR_RETURN ((LM_ERROR,
294 ACE_TEXT ("(%N:%l) AST_Union::")
295 ACE_TEXT ("in_recursion - ")
296 ACE_TEXT ("bad field type\n")),
300 if (type->in_recursion (list))
302 if (self_test)
303 this->in_recursion_ = 1;
304 idl_global->recursive_type_seen_ = true;
305 return true;
310 // Not in recursion.
311 if (self_test)
312 this->in_recursion_ = 0;
313 return 0;
316 // Look up the default branch in union.
317 AST_UnionBranch *
318 AST_Union::lookup_default (void)
320 AST_UnionBranch *b = 0;
321 AST_Decl *d = 0;
323 for (UTL_ScopeActiveIterator i (this, UTL_Scope::IK_both);
324 !i.is_done();
325 i.next ())
327 d = i.item ();
329 if (d->node_type () == AST_Decl::NT_union_branch)
331 b = dynamic_cast<AST_UnionBranch*> (d);
333 if (b == 0)
335 continue;
338 if (b->label () != 0
339 && b->label ()->label_kind () == AST_UnionLabel::UL_default)
341 idl_global->err ()->error2 (UTL_Error::EIDL_MULTIPLE_BRANCH,
342 this,
344 return b;
349 return 0;
352 // Look up a branch by label.
353 AST_UnionBranch *
354 AST_Union::lookup_label (AST_UnionBranch *b)
356 AST_UnionLabel *label = b->label ();
357 AST_Expression *lv = label->label_val ();
359 if (label->label_val () == 0)
361 return b;
364 AST_Decl *d = 0;
365 AST_UnionBranch *fb = 0;
367 lv->set_ev (lv->coerce (this->pd_udisc_type));
369 if (lv->ev () == 0)
371 idl_global->err ()->eval_error (lv);
372 return b;
375 for (UTL_ScopeActiveIterator i (this, UTL_Scope::IK_decls);
376 !i.is_done();
377 i.next ())
379 d = i.item ();
381 if (d->node_type () == AST_Decl::NT_union_branch)
383 fb = dynamic_cast<AST_UnionBranch*> (d);
385 if (fb == 0)
387 continue;
390 if (fb->label() != 0
391 && fb->label ()->label_kind () == AST_UnionLabel::UL_label
392 && fb->label ()->label_val ()->compare (lv))
394 idl_global->err ()->error2 (UTL_Error::EIDL_MULTIPLE_BRANCH,
395 this,
397 return b;
402 return 0;
405 // Look up a branch in an enum which is the discriminator type for this
406 // union, based on the label value which must be an enumerator in that
407 // enum.
408 AST_UnionBranch *
409 AST_Union::lookup_enum (AST_UnionBranch *b)
411 AST_UnionLabel *label = b->label();
412 AST_Expression *lv = label->label_val ();
413 AST_Enum *e = dynamic_cast<AST_Enum*> (this->pd_disc_type);
414 AST_Decl *d = 0;
415 AST_UnionBranch *fb = 0;
417 if (e == 0)
419 return 0;
422 if (lv == 0)
424 return b;
427 // Expecting a symbol label.
428 if (lv->ec () != AST_Expression::EC_symbol)
430 idl_global->err ()->enum_val_expected (this,
431 label);
432 return b;
435 // See if the symbol defines a constant in the discriminator enum.
436 UTL_ScopedName *sn = lv->n ();
437 d = e->lookup_by_name (sn,
438 true);
440 if (d == 0 || d->defined_in () != e)
442 idl_global->err ()->enum_val_lookup_failure (this,
444 sn);
445 return b;
448 // OK, now see if this symbol is already used as the label of
449 // some other branch.
450 for (UTL_ScopeActiveIterator i (this, UTL_Scope::IK_decls);
451 !i.is_done();
452 i.next ())
454 d = i.item ();
456 if (d->node_type () == AST_Decl::NT_union_branch)
458 fb = dynamic_cast<AST_UnionBranch*> (d);
460 if (fb == 0)
462 continue;
465 if (fb->label() != 0
466 && fb->label ()->label_kind () == AST_UnionLabel::UL_label
467 && fb->label ()->label_val ()->compare (lv))
469 idl_global->err ()->error2 (UTL_Error::EIDL_MULTIPLE_BRANCH,
470 this,
472 return b;
477 return 0;
480 // Look up a branch by value. This is the top level branch label resolution
481 // entry point. It dispatches to the right lookup function depending on the
482 // union discriminator type.
483 AST_UnionBranch *
484 AST_Union::lookup_branch (AST_UnionBranch *branch)
486 AST_UnionLabel *label = 0;
488 if (branch != 0)
490 label = branch->label ();
493 if (label != 0)
495 if (label->label_kind () == AST_UnionLabel::UL_default)
497 return this->lookup_default ();
500 if (this->pd_udisc_type == AST_Expression::EV_enum)
502 // CONVENTION: indicates enum discriminant.
503 return this->lookup_enum (branch);
506 return this->lookup_label (branch);
509 return 0;
512 // Return the default value.
514 AST_Union::default_value (AST_Union::DefaultValue &dv)
516 if (this->default_value_.computed_ == -2)
518 // We need to compute it.
519 if (this->compute_default_value () == -1)
521 ACE_ERROR_RETURN ((LM_ERROR,
522 ACE_TEXT ("(%N:%l) AST_Union::")
523 ACE_TEXT ("default_value - ")
524 ACE_TEXT ("Error computing ")
525 ACE_TEXT ("default value\n")),
526 -1);
530 dv = this->default_value_;
531 return 0;
534 // Determine the default value (if any).
536 AST_Union::compute_default_value (void)
538 // Check if we really need a default value. This will be true if there is an
539 // explicit default case OR if an implicit default exists because not all
540 // values of the discriminant type are covered by the cases.
542 // Compute the total true "case" labels i.e., exclude the "default" case.
543 ACE_UINT64 total_case_members = 0;
545 // In the case of a (unsigned) long long discriminant being fully used
546 // the total case count would actually overflow back to zero.
547 // This is 'end of days' programming but what the heck. We're here now.
548 bool first_case_found = false;
550 // Instantiate a scope iterator.
551 for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls);
552 !si.is_done ();
553 si.next ())
555 // Get the next AST decl node.
556 AST_UnionBranch *ub = dynamic_cast<AST_UnionBranch*> (si.item ());
558 if (ub != 0)
560 // If the label is a case label, increment by 1.
561 for (unsigned long i = 0; i < ub->label_list_length (); ++i)
563 if (ub->label (i)->label_kind () == AST_UnionLabel::UL_label)
565 ++total_case_members;
566 first_case_found = true;
572 // Check if the total_case_members cover the entire
573 // range of values that are permitted by the discriminant type. If they do,
574 // then a default value is not necessary. However, if such an explicit
575 // default case is provided, it must be flagged off as an error. Our
576 // front-end is not able to handle such a case since it is a semantic error
577 // and not a syntax error. Such an error is caught here.
579 switch (this->udisc_type ())
581 case AST_Expression::EV_short:
582 case AST_Expression::EV_ushort:
583 if (total_case_members > ACE_UINT16_MAX)
585 this->default_value_.computed_ = 0;
588 break;
589 case AST_Expression::EV_long:
590 case AST_Expression::EV_ulong:
591 case AST_Expression::EV_enum:
592 // Enums in CORBA are always 32bits in size, so unless
593 // there are that many enum labels in the set, it is
594 // incomplete (reguardless as to the actual member_count).
595 if (total_case_members > ACE_UINT32_MAX)
597 this->default_value_.computed_ = 0;
600 break;
601 case AST_Expression::EV_longlong:
602 case AST_Expression::EV_ulonglong:
603 // We would wrap to 0 here - we are using a 64 bit count
604 if (first_case_found && total_case_members == 0)
606 // If anyone ever produces a "default clause is invalid here" error
607 // after passing through here I will buy them a a house.
608 this->default_value_.computed_ = 0;
611 break;
612 case AST_Expression::EV_char:
613 case AST_Expression::EV_int8:
614 if (total_case_members > ACE_INT8_MAX)
616 this->default_value_.computed_ = 0;
619 break;
620 case AST_Expression::EV_uint8:
621 case AST_Expression::EV_octet:
622 if (total_case_members > ACE_UINT8_MAX)
624 this->default_value_.computed_ = 0;
627 break;
628 case AST_Expression::EV_wchar:
629 if (total_case_members == ACE_WCHAR_MAX + 1)
631 this->default_value_.computed_ = 0;
634 break;
635 case AST_Expression::EV_bool:
636 if (total_case_members == 2)
638 this->default_value_.computed_ = 0;
641 break;
642 default:
643 // Error.
644 this->default_value_.computed_ = -1;
645 ACE_ERROR_RETURN ((LM_ERROR,
646 ACE_TEXT ("(%N:%l) AST_Union::compute_default_value")
647 ACE_TEXT (" - Bad discriminant type\n")),
648 -1);
649 ACE_NOTREACHED (break;)
650 } // End of switch
652 // If we have determined that we don't have a default case and even then a
653 // default case was provided, flag this off as error.
654 if ((this->default_value_.computed_ == 0)
655 && (this->default_index () != -1))
657 // Error.
658 this->default_value_.computed_ = -1;
659 ACE_ERROR_RETURN ((LM_ERROR,
660 ACE_TEXT ("(%N:%l) AST_Union::compute_default_value")
661 ACE_TEXT (" - default clause is invalid here\n")),
662 -1);
665 // Proceed only if necessary.
666 switch (this->default_value_.computed_)
668 case -1:
669 // Error. We should never be here because errors
670 // have already been caught
671 // above.
672 return -1;
673 case 0:
674 // Nothing more to do.
675 return 0;
676 default:
677 // Proceed further down.
678 break;
681 // Initialization of the default value data member.
682 switch (this->udisc_type ())
684 case AST_Expression::EV_short:
685 this->default_value_.u.short_val = ACE_INT16_MIN;
686 break;
687 case AST_Expression::EV_ushort:
688 this->default_value_.u.ushort_val = 0;
689 break;
690 case AST_Expression::EV_long:
691 // The +1 is to avert a warning on many compilers.
692 this->default_value_.u.long_val = ACE_INT32_MIN + 1;
693 break;
694 case AST_Expression::EV_ulong:
695 this->default_value_.u.ulong_val = 0;
696 break;
697 case AST_Expression::EV_uint8:
698 case AST_Expression::EV_octet:
699 case AST_Expression::EV_int8:
700 case AST_Expression::EV_char:
701 this->default_value_.u.char_val = 0;
702 break;
703 case AST_Expression::EV_wchar:
704 this->default_value_.u.wchar_val = 0;
705 break;
706 case AST_Expression::EV_bool:
707 this->default_value_.u.bool_val = 0;
708 break;
709 case AST_Expression::EV_enum:
710 this->default_value_.u.enum_val = 0;
711 break;
712 case AST_Expression::EV_longlong:
713 this->default_value_.u.longlong_val = 0;
714 break;
715 case AST_Expression::EV_ulonglong:
716 this->default_value_.u.ulonglong_val = 0;
717 break;
718 default:
719 // Error caught earlier.
720 break;
723 // Proceed until we have found the appropriate default value.
724 while (this->default_value_.computed_ == -2)
726 int break_loop = 0;
728 // Instantiate a scope iterator.
729 for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls);
730 !si.is_done () && break_loop == 0;
731 si.next ())
733 // Get the next AST decl node
734 AST_UnionBranch *ub = dynamic_cast<AST_UnionBranch*> (si.item ());
736 if (ub != 0)
738 for (unsigned long i = 0;
739 i < ub->label_list_length () && !break_loop;
740 ++i)
742 if (ub->label (i)->label_kind () == AST_UnionLabel::UL_label)
744 // Not a default.
745 AST_Expression *expr = ub->label (i)->label_val ();
747 if (expr == 0)
749 // Error.
750 this->default_value_.computed_ = -1;
751 ACE_ERROR_RETURN ((
752 LM_ERROR,
753 ACE_TEXT ("(%N:%l) AST_Union::")
754 ACE_TEXT ("compute_default_value - ")
755 ACE_TEXT ("Bad case label value\n")),
760 switch (expr->ev ()->et)
762 // Check if they match in which case this
763 // cannot be the implicit default value. So
764 // start with a new value and try the whole loop
765 // again because our case labels may not be sorted.
766 case AST_Expression::EV_short:
767 if (this->default_value_.u.short_val
768 == expr->ev ()->u.sval)
770 this->default_value_.u.short_val++;
771 break_loop = 1;
774 break;
775 case AST_Expression::EV_ushort:
776 if (this->default_value_.u.ushort_val
777 == expr->ev ()->u.usval)
779 this->default_value_.u.ushort_val++;
780 break_loop = 1;
783 break;
784 case AST_Expression::EV_long:
785 if (this->default_value_.u.long_val
786 == expr->ev ()->u.lval)
788 this->default_value_.u.long_val++;
789 break_loop = 1;
792 break;
793 case AST_Expression::EV_ulong:
794 if (this->default_value_.u.ulong_val
795 == expr->ev ()->u.ulval)
797 this->default_value_.u.ulong_val++;
798 break_loop = 1;
801 break;
802 case AST_Expression::EV_uint8:
803 case AST_Expression::EV_octet:
804 case AST_Expression::EV_int8:
805 case AST_Expression::EV_char:
806 if (this->default_value_.u.char_val
807 == expr->ev ()->u.cval)
809 this->default_value_.u.char_val++;
810 break_loop = 1;
813 break;
814 case AST_Expression::EV_wchar:
815 if (this->default_value_.u.wchar_val
816 == expr->ev ()->u.wcval)
818 this->default_value_.u.wchar_val++;
819 break_loop = 1;
822 break;
823 case AST_Expression::EV_bool:
824 if (this->default_value_.u.bool_val
825 == expr->ev ()->u.bval)
827 this->default_value_.u.bool_val ^= true;
828 break_loop = 1;
831 break;
832 case AST_Expression::EV_enum:
833 // this is the case of enums. We maintain
834 // evaluated values which always start with 0
835 if (this->default_value_.u.enum_val
836 == expr->ev ()->u.eval)
838 this->default_value_.u.enum_val++;
839 break_loop = 1;
842 break;
843 case AST_Expression::EV_longlong:
844 if (this->default_value_.u.longlong_val
845 == expr->ev ()->u.llval)
847 this->default_value_.u.longlong_val++;
848 break_loop = 1;
851 break;
852 case AST_Expression::EV_ulonglong:
853 if (this->default_value_.u.ulonglong_val
854 == expr->ev ()->u.ullval)
856 this->default_value_.u.ulonglong_val++;
857 break_loop = 1;
860 break;
861 default:
862 // Error.
863 break;
864 } // End of switch.
865 } // if label_Kind == label
866 } // End of for loop going thru all labels.
867 } // If valid union branch.
868 } // End of while scope iterator loop.
870 // We have not aborted the inner loops which means we have found the
871 // default value.
872 if (break_loop == 0)
874 this->default_value_.computed_ = 1;
877 } // End of outer while (default_value.computed == -2).
879 return 0;
882 // Private operations.
884 // Compute the default index.
886 AST_Union::compute_default_index (void)
888 AST_Decl *d = 0;
889 AST_UnionBranch *ub = 0;
890 int i = 0;
892 // If default case does not exist, it will have a value of -1 according to
893 // the spec.
894 this->default_index_ = -1;
896 // If there are elements in this scope...
897 if (this->nmembers () > 0)
899 // Instantiate a scope iterator.
900 for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls);
901 !si.is_done ();
902 si.next ())
904 // Get the next AST decl node.
905 d = si.item ();
907 // If an enum is declared in our scope, its members are
908 // added to our scope as well, to detect clashes.
909 if (d->node_type () == AST_Decl::NT_enum_val)
911 continue;
914 if (!d->imported ())
916 ub = dynamic_cast<AST_UnionBranch*> (d);
918 for (unsigned long j = 0; j < ub->label_list_length (); ++j)
920 // Check if we are printing the default case.
921 AST_UnionLabel::UnionLabel ulk = ub->label (j)->label_kind ();
922 if (ulk == AST_UnionLabel::UL_default)
924 // Zero based indexing.
925 this->default_index_ = i;
929 // TAO's Typecode class keeps only a member count (not
930 // a label count) so this increment has been moved
931 // out of the inner loop.
932 ++i;
937 return 0;
940 // Redefinition of inherited virtual operations
942 AST_UnionBranch *
943 AST_Union::fe_add_union_branch (AST_UnionBranch *t)
945 return dynamic_cast<AST_UnionBranch*> (this->fe_add_ref_decl (t));
948 AST_Union *
949 AST_Union::fe_add_union (AST_Union *t)
951 return dynamic_cast<AST_Union*> (this->fe_add_full_struct_type (t));
954 AST_Structure *
955 AST_Union::fe_add_structure (AST_Structure *t)
957 return this->fe_add_full_struct_type (t);
960 AST_Enum *
961 AST_Union::fe_add_enum (AST_Enum *t)
963 return dynamic_cast<AST_Enum*> (this->fe_add_decl (t));
966 // Add this AST_EnumVal node (enumerator declaration) to this scope.
967 // This is done to conform to the C++ scoping rules which declare
968 // enumerators in the enclosing scope (in addition to declaring them
969 // in the enum itself).
970 AST_EnumVal *
971 AST_Union::fe_add_enum_val (AST_EnumVal *t)
973 return dynamic_cast<AST_EnumVal*> (this->fe_add_decl (t));
976 // Dump this AST_Union node to the ostream o.
977 void
978 AST_Union::dump (ACE_OSTREAM_TYPE &o)
980 o << "union ";
981 this->local_name ()->dump (o);
982 o << " switch (";
983 AST_Annotation_Appls::iterator i,
984 finished = disc_annotations ().end ();
985 for (i = disc_annotations ().begin (); i != finished; ++i)
987 AST_Annotation_Appl *a = i->get ();
988 a->dump (o);
989 dump_i (o, " ");
991 this->pd_disc_type->local_name ()->dump (o);
992 o << ") {\n";
993 UTL_Scope::dump (o);
994 idl_global->indent ()->skip_to (o);
995 o << "}";
998 // Compute the size type of the node in question.
1000 AST_Union::compute_size_type (void)
1002 for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls);
1003 !si.is_done ();
1004 si.next ())
1006 // Get the next AST decl node.
1007 AST_Decl *d = si.item ();
1009 if (d->node_type () == AST_Decl::NT_enum_val)
1011 continue;
1014 AST_Field *f = dynamic_cast<AST_Field*> (d);
1016 if (f != 0)
1018 AST_Type *t = f->field_type ();
1019 // Our sizetype depends on the sizetype of our members. Although
1020 // previous value of sizetype may get overwritten, we are
1021 // guaranteed by the "size_type" call that once the value reached
1022 // be_decl::VARIABLE, nothing else can overwrite it.
1023 this->size_type (t->size_type ());
1025 else
1027 ACE_DEBUG ((LM_DEBUG,
1028 "WARNING (%N:%l) be_union::compute_size_type - "
1029 "dynamic_cast returned 0\n"));
1033 return 0;
1037 AST_Union::ast_accept (ast_visitor *visitor)
1039 return visitor->visit_union (this);
1042 // Data accessors.
1044 AST_ConcreteType *
1045 AST_Union::disc_type (void)
1047 return this->pd_disc_type;
1050 AST_Expression::ExprType
1051 AST_Union::udisc_type (void)
1053 return this->pd_udisc_type;
1056 IMPL_NARROW_FROM_DECL(AST_Union)
1057 IMPL_NARROW_FROM_SCOPE(AST_Union)
1059 AST_Annotation_Appls &
1060 AST_Union::disc_annotations ()
1062 return disc_annotations_;
1065 void
1066 AST_Union::disc_annotations (const AST_Annotation_Appls &annotations)
1068 disc_annotations_ = annotations;