diff options
author | parsons <parsons@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-02-07 21:30:05 +0000 |
---|---|---|
committer | parsons <parsons@ae88bc3d-4319-0410-8dbf-d08b4c9d3795> | 2000-02-07 21:30:05 +0000 |
commit | 998981960b60780e9c35e963174d50c0297523a7 (patch) | |
tree | b8121cf728fdd12adbde46c96976c5df3d06cc31 /TAO/TAO_IDL/be/be_visitor_union | |
parent | 5f80b562f3f12dd52595c839ef5c18830b03e344 (diff) | |
download | ATCD-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.cpp | 5 | ||||
-rw-r--r-- | TAO/TAO_IDL/be/be_visitor_union/union_ci.cpp | 84 | ||||
-rw-r--r-- | TAO/TAO_IDL/be/be_visitor_union/union_cs.cpp | 4 |
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); |