2 //=============================================================================
6 * Generic visitor generating code for Unions
8 * @author Aniruddha Gokhale
10 //=============================================================================
14 be_visitor_union::be_visitor_union (be_visitor_context
*ctx
)
15 : be_visitor_scope (ctx
)
19 be_visitor_union::~be_visitor_union ()
24 be_visitor_union::visit_union (be_union
*)
26 return -1; // Must be overriden.
30 be_visitor_union::visit_union_branch (be_union_branch
*node
)
32 // Instantiate a visitor context with a copy of our context. This info
33 // will be modified based on what type of node we are visiting.
34 be_visitor_context
ctx (*this->ctx_
);
38 switch (this->ctx_
->state ())
40 case TAO_CodeGen::TAO_UNION_PUBLIC_CH
:
42 be_visitor_union_branch_public_ch
visitor (&ctx
);
43 status
= node
->accept (&visitor
);
46 case TAO_CodeGen::TAO_UNION_PRIVATE_CH
:
48 be_visitor_union_branch_private_ch
visitor (&ctx
);
49 status
= node
->accept (&visitor
);
52 case TAO_CodeGen::TAO_ROOT_CI
:
54 be_visitor_union_branch_public_ci
visitor (&ctx
);
55 status
= node
->accept (&visitor
);
58 case TAO_CodeGen::TAO_UNION_PUBLIC_CS
:
60 be_visitor_union_branch_public_cs
visitor (&ctx
);
61 status
= node
->accept (&visitor
);
64 case TAO_CodeGen::TAO_UNION_PUBLIC_ASSIGN_CS
:
66 be_visitor_union_branch_public_assign_cs
visitor (&ctx
);
67 status
= node
->accept (&visitor
);
70 case TAO_CodeGen::TAO_UNION_PUBLIC_RESET_CS
:
72 be_visitor_union_branch_public_reset_cs
visitor (&ctx
);
73 status
= node
->accept (&visitor
);
76 case TAO_CodeGen::TAO_ROOT_CDR_OP_CH
:
78 be_visitor_union_branch_cdr_op_ch
visitor (&ctx
);
79 status
= node
->accept (&visitor
);
82 case TAO_CodeGen::TAO_ROOT_CDR_OP_CS
:
84 be_visitor_union_branch_cdr_op_cs
visitor (&ctx
);
85 status
= node
->accept (&visitor
);
90 ACE_ERROR_RETURN ((LM_ERROR
,
91 "(%N:%l) be_visitor_union::"
92 "visit_union_branch - "
93 "Bad context state\n"),
100 ACE_ERROR_RETURN ((LM_ERROR
,
101 "(%N:%l) be_visitor_union::"
102 "visit_union_branch - "
103 "failed to accept visitor\n"),
110 be_visitor_union::BoolUnionBranch
111 be_visitor_union::boolean_branch (be_union_branch
*b
)
113 be_union
*u
= dynamic_cast<be_union
*> (b
->defined_in ());
114 if (!u
|| u
->udisc_type () != AST_Expression::EV_bool
)
117 bool br_d
= false, br_t
= false, br_f
= false;
118 for (unsigned long i
= 0; i
< b
->label_list_length (); ++i
)
119 if (b
->label (i
)->label_kind () == AST_UnionLabel::UL_default
)
122 (b
->label (i
)->label_val ()->ev ()->u
.bval
? br_t
: br_f
) = true;
124 if ((br_t
&& br_f
) || (u
->nfields () == 1 && br_d
))
125 return BUB_UNCONDITIONAL
;
127 bool has_other
= false, other_val
= false;
128 for (unsigned int i
= 0; br_d
&& i
< u
->nfields (); ++i
)
134 AST_UnionBranch
*other
= dynamic_cast<AST_UnionBranch
*> (*f
);
135 for (unsigned long j
= 0; j
< other
->label_list_length (); ++j
)
138 other_val
= other
->label (j
)->label_val ()->ev ()->u
.bval
;
143 return (br_t
|| (has_other
&& !other_val
)) ? BUB_TRUE
: BUB_FALSE
;
147 be_visitor_union_cdr_op_cs::pre_process (be_decl
*bd
)
149 if (this->ctx_
->sub_state () == TAO_CodeGen::TAO_CDR_SCOPE
)
154 // Enum val nodes are added just to help check reference
155 // clashes, since an enum declared in our scope is not itself
157 if (bd
->node_type () == AST_Decl::NT_enum_val
)
162 TAO_OutStream
*os
= this->ctx_
->stream ();
165 dynamic_cast<be_union_branch
*> (bd
);
167 // Could be a type decl.
173 this->latest_branch_
= boolean_branch (b
);
174 if (this->latest_branch_
!= BUB_NONE
) {
175 if (this->latest_branch_
!= BUB_UNCONDITIONAL
) {
176 *os
<< "if (" << (this->latest_branch_
== BUB_TRUE
? "" : "!")
177 << (this->ctx_
->sub_state () == TAO_CodeGen::TAO_CDR_OUTPUT
?
178 "_tao_union._d ()" : "_tao_discriminant") << ")" << be_idt_nl
186 for (unsigned long i
= 0; i
< b
->label_list_length (); ++i
)
188 // check if we are printing the default case
189 if (b
->label (i
)->label_kind () == AST_UnionLabel::UL_default
)
197 b
->gen_label_value (os
, i
);
202 if (i
== (b
->label_list_length () - 1))
212 *os
<< "{" << be_idt_nl
;
218 be_visitor_union_cdr_op_cs::post_process (be_decl
*bd
)
220 if (this->ctx_
->sub_state () == TAO_CodeGen::TAO_CDR_SCOPE
)
225 if (bd
->node_type () == AST_Decl::NT_enum_val
)
230 TAO_OutStream
*os
= this->ctx_
->stream ();
232 switch (this->latest_branch_
)
235 *os
<< be_uidt_nl
<< "}" << be_nl
<< "break;" << be_uidt
;
239 *os
<< be_uidt_nl
<< "}" << be_uidt_nl
<< be_nl
;
241 case BUB_UNCONDITIONAL
: