summaryrefslogtreecommitdiff
path: root/TAO/TAO_IDL/be/be_visitor_union
diff options
context:
space:
mode:
authorparsons <parsons@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2000-02-07 21:30:05 +0000
committerparsons <parsons@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2000-02-07 21:30:05 +0000
commit998981960b60780e9c35e963174d50c0297523a7 (patch)
treeb8121cf728fdd12adbde46c96976c5df3d06cc31 /TAO/TAO_IDL/be/be_visitor_union
parent5f80b562f3f12dd52595c839ef5c18830b03e344 (diff)
downloadATCD-998981960b60780e9c35e963174d50c0297523a7.tar.gz
Code generation for unions with duplicate case labels.
Diffstat (limited to 'TAO/TAO_IDL/be/be_visitor_union')
-rw-r--r--TAO/TAO_IDL/be/be_visitor_union/union_ch.cpp5
-rw-r--r--TAO/TAO_IDL/be/be_visitor_union/union_ci.cpp84
-rw-r--r--TAO/TAO_IDL/be/be_visitor_union/union_cs.cpp4
3 files changed, 87 insertions, 6 deletions
diff --git a/TAO/TAO_IDL/be/be_visitor_union/union_ch.cpp b/TAO/TAO_IDL/be/be_visitor_union/union_ch.cpp
index 89ad80b0667..ecbd98a907b 100644
--- a/TAO/TAO_IDL/be/be_visitor_union/union_ch.cpp
+++ b/TAO/TAO_IDL/be/be_visitor_union/union_ch.cpp
@@ -157,8 +157,9 @@ int be_visitor_union_ch::visit_union (be_union *node)
os->decr_indent ();
*os << "private:\n";
os->incr_indent ();
- *os << bt->nested_type_name (node) << " disc_;" << be_nl; // emit the
- // ACE_NESTED_CLASS macro
+ *os << bt->nested_type_name (node) << " disc_;" << be_nl;
+ *os << bt->nested_type_name (node) << " holder_;" << be_nl;
+ // Emit the ACE_NESTED_CLASS macro.
// the members are inside of a union
*os << "union" << be_nl;
diff --git a/TAO/TAO_IDL/be/be_visitor_union/union_ci.cpp b/TAO/TAO_IDL/be/be_visitor_union/union_ci.cpp
index 91fa1eec0f8..acbb10db206 100644
--- a/TAO/TAO_IDL/be/be_visitor_union/union_ci.cpp
+++ b/TAO/TAO_IDL/be/be_visitor_union/union_ci.cpp
@@ -75,9 +75,87 @@ int be_visitor_union_ci::visit_union (be_union *node)
*os << "// returns pointer to the discriminant" << be_nl;
*os << "ACE_INLINE void *" << be_nl
<< node->name () << "::_discriminant (void)" << be_nl
- << "{" << be_idt_nl
- << "return &this->disc_;" << be_uidt_nl
- << "}\n\n";
+ << "{" << be_idt_nl;
+
+ if (node->has_duplicate_case_labels ())
+ {
+ // If there are duplicate case labels, we may have to
+ // modify what this generated function returns, so that
+ // the ORB function that called it can find a match with
+ // the value found in the typecode.
+ *os << "switch (this->disc_)" << be_idt_nl;
+ *os << "{" << be_idt_nl;
+
+ AST_Decl *d;
+ be_union_branch *ub;
+ UTL_ScopeActiveIterator *si =
+ new UTL_ScopeActiveIterator (node,
+ UTL_Scope::IK_decls);
+
+ while (!si->is_done())
+ {
+ d = si->item ();
+ ub = be_union_branch::narrow_from_decl (d);
+ AST_UnionLabel *ul = ub->label (0);
+
+ if (ul->label_kind () == AST_UnionLabel::UL_label)
+ {
+ // Map the actual discriminant value to the value
+ // of the first value encountered for that member,
+ // because that is the value that will be found in
+ // the typecode.
+ for (unsigned int i = 0; i < ub->label_list_length (); i++)
+ {
+ *os << "case ";
+ ub->gen_label_value (os, i);
+ *os << ":" << be_idt_nl;
+ *os << "this->holder_ = ";
+ ub->gen_label_value (os, 0);
+ *os << ";" << be_nl;
+ *os << "break;" << be_uidt_nl;
+ }
+ }
+
+ si->next ();
+ }
+
+ delete si;
+
+ *os << "default:" << be_idt_nl;
+
+ be_union::DefaultValue dv;
+ if (node->default_value (dv) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_visitor_union_ci::"
+ "visit_union - "
+ "computing default value failed\n"),
+ -1);
+ }
+
+ // If we have an implicit or explicit default case, we must
+ // set the return value to some legal default value.
+ // Otherwise, we do nothing - this case will not be reached,
+ // but it makes some comilers happy to have it there.
+ if ((dv.computed_ != 0))
+ {
+ *os << "this->holder_ = ";
+ ub->gen_default_label_value (os, node);
+ *os << ";" << be_nl;
+ }
+
+ *os << "break;" << be_uidt << be_uidt_nl;
+
+ *os << "}" << be_uidt_nl << be_nl;
+ *os << "return &this->holder_;" << be_uidt_nl;
+ }
+ // If there are no duplicate case labels, this sufficient.
+ else
+ {
+ *os << "return &this->disc_;" << be_uidt_nl;
+ }
+
+ *os << "}\n\n";
// the discriminant type may have to be defined here if it was an enum
// declaration inside of the union statement.
diff --git a/TAO/TAO_IDL/be/be_visitor_union/union_cs.cpp b/TAO/TAO_IDL/be/be_visitor_union/union_cs.cpp
index 1ad24ad936a..42381edd7df 100644
--- a/TAO/TAO_IDL/be/be_visitor_union/union_cs.cpp
+++ b/TAO/TAO_IDL/be/be_visitor_union/union_cs.cpp
@@ -141,7 +141,9 @@ int be_visitor_union_cs::visit_union (be_union *node)
ub->gen_default_label_value (os, node);
}
- *os << ";" << be_uidt_nl << "}" << be_nl << be_nl;
+ *os << ";";
+
+ *os << be_uidt_nl << "}" << be_nl << be_nl;
this->ctx_->state (TAO_CodeGen::TAO_UNION_PUBLIC_ASSIGN_CS);