diff options
-rw-r--r-- | TAO/TAO_IDL/be/be_visitor_union/cdr_op_cs.cpp | 44 | ||||
-rw-r--r-- | TAO/TAO_IDL/be/be_visitor_union/union.cpp | 63 | ||||
-rw-r--r-- | TAO/TAO_IDL/be/be_visitor_union/union_cs.cpp | 56 | ||||
-rw-r--r-- | TAO/TAO_IDL/be/be_visitor_union_branch/public_assign_cs.cpp | 66 | ||||
-rw-r--r-- | TAO/TAO_IDL/be/be_visitor_union_branch/public_reset_cs.cpp | 93 | ||||
-rw-r--r-- | TAO/TAO_IDL/be_include/be_visitor_union/cdr_op_cs.h | 3 | ||||
-rw-r--r-- | TAO/TAO_IDL/be_include/be_visitor_union/union.h | 4 | ||||
-rw-r--r-- | TAO/tests/IDL_Test/interface.idl | 2 | ||||
-rw-r--r-- | TAO/tests/IDL_Test/union.idl | 19 |
9 files changed, 251 insertions, 99 deletions
diff --git a/TAO/TAO_IDL/be/be_visitor_union/cdr_op_cs.cpp b/TAO/TAO_IDL/be/be_visitor_union/cdr_op_cs.cpp index 9ebe2f0415d..96286c8a611 100644 --- a/TAO/TAO_IDL/be/be_visitor_union/cdr_op_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_union/cdr_op_cs.cpp @@ -84,9 +84,12 @@ be_visitor_union_cdr_op_cs::visit_union (be_union *node) << ")" << be_uidt_nl << "{" << be_idt_nl; + bool boolDisc = false; + switch (node->udisc_type ()) { case AST_Expression::EV_bool: + boolDisc = true; *os << "::ACE_OutputCDR::from_boolean tmp (_tao_union._d ());" << be_nl << "if ( !(strm << tmp) )" << be_idt_nl; @@ -110,9 +113,13 @@ be_visitor_union_cdr_op_cs::visit_union (be_union *node) *os << "{" << be_idt_nl << "return false;" << be_uidt_nl << "}" << be_uidt_nl << be_nl - << "::CORBA::Boolean result = true;" << be_nl_2 - << "switch (_tao_union._d ())" << be_nl - << "{" << be_idt; + << "::CORBA::Boolean result = true;" << be_nl_2; + + if (!boolDisc) + { + *os << "switch (_tao_union._d ())" << be_nl + << "{" << be_idt; + } if (this->visit_scope (node) == -1) { @@ -129,14 +136,18 @@ be_visitor_union_cdr_op_cs::visit_union (be_union *node) // not all case values are included. If there is no // implicit default case, or the discriminator is not // an enum, this does no harm. - if (node->gen_empty_default_label ()) + if (!boolDisc && node->gen_empty_default_label ()) { *os << be_nl << "default:" << be_idt_nl; *os << "break;"<< be_uidt; } - *os << be_uidt_nl << "}" << be_nl_2 - << "return result;" << be_uidt_nl + if (!boolDisc) + { + *os << be_uidt_nl << "}" << be_nl_2; + } + + *os << "return result;" << be_uidt_nl << "}" << be_nl_2; // Set the substate as generating code for the input operator. @@ -180,9 +191,13 @@ be_visitor_union_cdr_op_cs::visit_union (be_union *node) *os << "{" << be_idt_nl << "return false;" << be_uidt_nl << "}" << be_uidt_nl << be_nl - << "::CORBA::Boolean result = true;" << be_nl_2 - << "switch (_tao_discriminant)" << be_nl - << "{" << be_idt; + << "::CORBA::Boolean result = true;" << be_nl_2; + + if (!boolDisc) + { + *os << "switch (_tao_discriminant)" << be_nl + << "{" << be_idt; + } if (this->visit_scope (node) == -1) { @@ -199,7 +214,7 @@ be_visitor_union_cdr_op_cs::visit_union (be_union *node) // not all case values are included. If there is no // implicit default case, or the discriminator is not // an enum, this does no harm. - if (node->gen_empty_default_label ()) + if (!boolDisc && node->gen_empty_default_label ()) { *os << be_nl; *os << "default:" << be_idt_nl; @@ -209,9 +224,12 @@ be_visitor_union_cdr_op_cs::visit_union (be_union *node) *os << "break;" << be_uidt; } - *os << be_uidt_nl - << "}" << be_nl_2 - << "return result;" << be_uidt_nl + if (!boolDisc) + { + *os << be_uidt_nl << "}" << be_nl_2; + } + + *os << "return result;" << be_uidt_nl << "}" << be_nl; bool use_underscore = (this->ctx_->tdef () == 0); diff --git a/TAO/TAO_IDL/be/be_visitor_union/union.cpp b/TAO/TAO_IDL/be/be_visitor_union/union.cpp index 1b91aed257b..a9570f787ba 100644 --- a/TAO/TAO_IDL/be/be_visitor_union/union.cpp +++ b/TAO/TAO_IDL/be/be_visitor_union/union.cpp @@ -107,6 +107,42 @@ be_visitor_union::visit_union_branch (be_union_branch *node) return 0; } +be_visitor_union::BoolUnionBranch +be_visitor_union::boolean_branch (be_union_branch *b) +{ + be_union *u = be_union::narrow_from_scope (b->defined_in ()); + if (!u || u->udisc_type () != AST_Expression::EV_bool) + return BUB_NONE; + + bool br_d = false, br_t = false, br_f = false; + for (unsigned long i = 0; i < b->label_list_length (); ++i) + if (b->label (i)->label_kind () == AST_UnionLabel::UL_default) + br_d = true; + else + (b->label (i)->label_val ()->ev ()->u.bval ? br_t : br_f) = true; + + if ((br_t && br_f) || (u->nfields () == 1 && br_d)) + return BUB_UNCONDITIONAL; + + bool has_other = false, other_val; + for (unsigned int i = 0; br_d && i < u->nfields (); ++i) + { + AST_Field **f; + u->field (f, i); + if (*f != b) + { + AST_UnionBranch *other = AST_UnionBranch::narrow_from_decl (*f); + for (unsigned long j = 0; j < other->label_list_length (); ++j) + { + has_other = true; + other_val = other->label (j)->label_val ()->ev ()->u.bval; + } + } + } + + return (br_t || (has_other && !other_val)) ? BUB_TRUE : BUB_FALSE; +} + int be_visitor_union_cdr_op_cs::pre_process (be_decl *bd) { @@ -134,6 +170,19 @@ be_visitor_union_cdr_op_cs::pre_process (be_decl *bd) return 0; } + this->latest_branch_ = boolean_branch (b); + switch (this->latest_branch_) + { + case BUB_TRUE: + case BUB_FALSE: + *os << "if (" << (this->latest_branch_ == BUB_TRUE ? "" : "!") + << (this->ctx_->sub_state () == TAO_CodeGen::TAO_CDR_OUTPUT ? + "_tao_union._d ()" : "_tao_discriminant") << ")" << be_idt_nl + << "{" << be_idt_nl; + case BUB_UNCONDITIONAL: + return 0; + } + *os << be_nl; for (unsigned long i = 0; i < b->label_list_length (); ++i) @@ -182,8 +231,18 @@ be_visitor_union_cdr_op_cs::post_process (be_decl *bd) TAO_OutStream *os = this->ctx_->stream (); - *os << be_uidt_nl << "}" << be_nl - << "break;" << be_uidt; + switch (this->latest_branch_) + { + case BUB_NONE: + *os << be_uidt_nl << "}" << be_nl << "break;" << be_uidt; + break; + case BUB_TRUE: + case BUB_FALSE: + *os << be_uidt_nl << "}" << be_uidt_nl << be_nl; + break; + case BUB_UNCONDITIONAL: + *os << be_nl; + } return 0; } 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 132c0338389..eb1cbd75784 100644 --- a/TAO/TAO_IDL/be/be_visitor_union/union_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_union/union_cs.cpp @@ -145,13 +145,19 @@ int be_visitor_union_cs::visit_union (be_union *node) // So we know we are generating the copy constructor. this->ctx_->sub_state (TAO_CodeGen::TAO_UNION_COPY_CONSTRUCTOR); + const bool boolDisc = node->udisc_type() == AST_Expression::EV_bool; + *os << node->name () << "::" << node->local_name () << " (const ::" << node->name () << " &u)" << be_nl; *os << "{" << be_idt_nl; *os << "this->disc_ = u.disc_;" << be_nl; - *os << "switch (this->disc_)" << be_nl; - *os << "{" << be_idt; + + if (!boolDisc) + { + *os << "switch (this->disc_)" << be_nl; + *os << "{" << be_idt; + } if (this->visit_scope (node) == -1) { @@ -168,15 +174,19 @@ int be_visitor_union_cs::visit_union (be_union *node) // not all case values are included. If there is no // implicit default case, or the discriminator is not // an enum, this does no harm. - if (node->gen_empty_default_label ()) + if (!boolDisc && node->gen_empty_default_label ()) { *os << be_nl << "default:" << be_nl << "break;"; } - *os << be_uidt_nl << "}" << be_uidt_nl - << "}" << be_nl_2; + if (!boolDisc) + { + *os << be_uidt_nl << "}"; + } + + *os << be_uidt_nl << "}" << be_nl_2; *os << node->name () << "::~" << node->local_name () << " (void)" << be_nl @@ -217,8 +227,11 @@ int be_visitor_union_cs::visit_union (be_union *node) *os << "this->_reset ();" << be_nl; *os << "this->disc_ = u.disc_;" << be_nl_2; // now switch based on the disc value - *os << "switch (this->disc_)" << be_nl; - *os << "{" << be_idt; + if (!boolDisc) + { + *os << "switch (this->disc_)" << be_nl; + *os << "{" << be_idt; + } if (this->visit_scope (node) == -1) { @@ -235,16 +248,19 @@ int be_visitor_union_cs::visit_union (be_union *node) // not all case values are included. If there is no // implicit default case, or the discriminator is not // an enum, this does no harm. - if (node->gen_empty_default_label ()) + if (!boolDisc && node->gen_empty_default_label ()) { *os << be_nl << "default:" << be_nl << "break;"; } - *os << be_uidt_nl - << "}" << be_nl_2; - *os << "return *this;" << be_uidt_nl; + if (!boolDisc) + { + *os << be_uidt_nl << "}" << be_nl; + } + + *os << be_nl << "return *this;" << be_uidt_nl; *os << "}" << be_nl_2; // The reset method. @@ -253,8 +269,12 @@ int be_visitor_union_cs::visit_union (be_union *node) *os << "/// Reset method to reset old values of a union." << be_nl; *os << "void " << node->name () << "::_reset (void)" << be_nl; *os << "{" << be_idt_nl; - *os << "switch (this->disc_)" << be_nl; - *os << "{" << be_idt_nl; + + if (!boolDisc) + { + *os << "switch (this->disc_)" << be_nl; + *os << "{" << be_idt_nl; + } if (this->visit_scope (node) == -1) { @@ -271,15 +291,19 @@ int be_visitor_union_cs::visit_union (be_union *node) // not all case values are included. If there is no // implicit default case, or the discriminator is not // an enum, this does no harm. - if (node->gen_empty_default_label ()) + if (!boolDisc && node->gen_empty_default_label ()) { *os << be_nl << "default:" << be_nl << "break;"; } - *os << be_uidt_nl << "}" << be_uidt_nl - << "}"; + if (!boolDisc) + { + *os << be_uidt_nl << "}"; + } + + *os << be_uidt_nl << "}"; if (be_global->tc_support ()) { diff --git a/TAO/TAO_IDL/be/be_visitor_union_branch/public_assign_cs.cpp b/TAO/TAO_IDL/be/be_visitor_union_branch/public_assign_cs.cpp index f08b853ebfa..14048d27395 100644 --- a/TAO/TAO_IDL/be/be_visitor_union_branch/public_assign_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_union_branch/public_assign_cs.cpp @@ -39,29 +39,41 @@ be_visitor_union_branch_public_assign_cs::visit_union_branch ( *os << be_nl; - // This visitor is used when we are generating the copy ctor and - // assignment operator for the union. - // Individual assignment of the members takes place inside a case - // statement because the type of member assigned is based on the value - // of the discriminant - for (unsigned long i = 0; - i < node->label_list_length (); - ++i) - { - // check if we are printing the default case - if (node->label (i)->label_kind () == AST_UnionLabel::UL_default) + const be_visitor_union::BoolUnionBranch bub = + be_visitor_union::boolean_branch (node); + + switch (bub) + { + case be_visitor_union::BUB_NONE: + // This visitor is used when we are generating the copy ctor and + // assignment operator for the union. + // Individual assignment of the members takes place inside a case + // statement because the type of member assigned is based on the value + // of the discriminant + for (unsigned long i = 0; + i < node->label_list_length (); + ++i) { - *os << "default:" << be_nl; + // check if we are printing the default case + if (node->label (i)->label_kind () == AST_UnionLabel::UL_default) + { + *os << "default:" << be_nl; + } + else + { + *os << "case "; + node->gen_label_value (os, i); + *os << ":" << be_nl; + } } - else - { - *os << "case "; - node->gen_label_value (os, i); - *os << ":" << be_nl; - } - } - *os << "{" << be_idt_nl; + *os << "{" << be_idt_nl; + break; + case be_visitor_union::BUB_TRUE: + case be_visitor_union::BUB_FALSE: + *os << "if (" << (bub == be_visitor_union::BUB_TRUE ? "" : "!") + << "this->disc_)" << be_idt_nl << "{" << be_idt_nl; + } // first generate the type information be_type *bt = be_type::narrow_from_decl (node->field_type ()); @@ -86,8 +98,18 @@ be_visitor_union_branch_public_assign_cs::visit_union_branch ( ), -1); } - *os << "}" << be_nl; - *os << "break;"; + switch (bub) + { + case be_visitor_union::BUB_NONE: + *os << "}" << be_nl << "break;"; + break; + case be_visitor_union::BUB_TRUE: + case be_visitor_union::BUB_FALSE: + *os << "}" << be_uidt_nl; + break; + case be_visitor_union::BUB_UNCONDITIONAL: + *os << be_nl; + } return 0; } diff --git a/TAO/TAO_IDL/be/be_visitor_union_branch/public_reset_cs.cpp b/TAO/TAO_IDL/be/be_visitor_union_branch/public_reset_cs.cpp index 02858973da9..3a27774b701 100644 --- a/TAO/TAO_IDL/be/be_visitor_union_branch/public_reset_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_union_branch/public_reset_cs.cpp @@ -48,23 +48,35 @@ be_visitor_union_branch_public_reset_cs::visit_union_branch ( *os << be_nl; - for (unsigned long i = 0; i < node->label_list_length (); ++i) + const be_visitor_union::BoolUnionBranch bub = + be_visitor_union::boolean_branch (node); + + switch (bub) { - // check if we are printing the default case - if (node->label (i)->label_kind () == AST_UnionLabel::UL_default) + case be_visitor_union::BUB_NONE: + for (unsigned long i = 0; i < node->label_list_length (); ++i) { - *os << "default:"; + // check if we are printing the default case + if (node->label (i)->label_kind () == AST_UnionLabel::UL_default) + { + *os << "default:"; + } + else + { + *os << "case "; + node->gen_label_value (os, i); + *os << ":"; + } + if (i == (node->label_list_length () - 1)) + *os << be_idt_nl; + else + *os << be_nl; } - else - { - *os << "case "; - node->gen_label_value (os, i); - *os << ":"; - } - if (i == (node->label_list_length () - 1)) - *os << be_idt_nl; - else - *os << be_nl; + break; + case be_visitor_union::BUB_TRUE: + case be_visitor_union::BUB_FALSE: + *os << "if (" << (bub == be_visitor_union::BUB_TRUE ? "" : "!") + << "this->disc_)" << be_idt_nl << "{" << be_idt_nl; } if (bt->accept (this) == -1) @@ -76,6 +88,16 @@ be_visitor_union_branch_public_reset_cs::visit_union_branch ( -1); } + switch (bub) + { + case be_visitor_union::BUB_NONE: + *os << be_uidt_nl << "break;" << be_nl; + break; + case be_visitor_union::BUB_TRUE: + case be_visitor_union::BUB_FALSE: + *os << be_uidt_nl << "}" << be_uidt_nl; + } + return 0; } @@ -143,8 +165,7 @@ be_visitor_union_branch_public_reset_cs::visit_array (be_array *node) *os << fname << "_free (this->u_." << ub->local_name () << "_);" << be_nl - << "this->u_." << ub->local_name () << "_ = 0;" << be_nl - << "break;" << be_uidt; + << "this->u_." << ub->local_name () << "_ = 0;" << be_nl; return 0; } @@ -166,9 +187,6 @@ be_visitor_union_branch_public_reset_cs::visit_enum (be_enum *) -1); } - TAO_OutStream *os = this->ctx_->stream (); - *os << "break;" << be_uidt; - return 0; } @@ -194,8 +212,7 @@ be_visitor_union_branch_public_reset_cs::visit_interface (be_interface *) *os << "delete this->u_." << ub->local_name () << "_;" << be_nl << "this->u_." << ub->local_name () - << "_ = 0;" << be_nl - << "break;" << be_uidt; + << "_ = 0;" << be_nl; return 0; } @@ -222,8 +239,7 @@ be_visitor_union_branch_public_reset_cs::visit_interface_fwd (be_interface_fwd * *os << "delete this->u_." << ub->local_name () << "_;" << be_nl << "this->u_." << ub->local_name () - << "_ = 0;" << be_nl - << "break;" << be_uidt; + << "_ = 0;" << be_nl; return 0; } @@ -251,8 +267,7 @@ be_visitor_union_branch_public_reset_cs::visit_valuebox ( *os << "delete this->u_." << ub->local_name () << "_;" << be_nl << "this->u_." << ub->local_name () - << "_ = 0;" << be_nl - << "break;" << be_uidt_nl; + << "_ = 0;" << be_nl; return 0; } @@ -280,8 +295,7 @@ be_visitor_union_branch_public_reset_cs::visit_valuetype ( *os << "delete this->u_." << ub->local_name () << "_;" << be_nl << "this->u_." << ub->local_name () - << "_ = 0;" << be_nl - << "break;" << be_uidt; + << "_ = 0;" << be_nl; return 0; } @@ -309,8 +323,7 @@ be_visitor_union_branch_public_reset_cs::visit_valuetype_fwd ( *os << "delete this->u_." << ub->local_name () << "_;" << be_nl << "this->u_." << ub->local_name () - << "_ = 0;" << be_nl - << "break;" << be_uidt; + << "_ = 0;" << be_nl; return 0; } @@ -342,31 +355,26 @@ be_visitor_union_branch_public_reset_cs::visit_predefined_type ( *os << "delete this->u_." << ub->local_name () << "_;" << be_nl; *os << "this->u_." << ub->local_name () - << "_ = 0;" << be_nl - << "break;" << be_uidt; + << "_ = 0;" << be_nl; break; case AST_PredefinedType::PT_pseudo: *os << "::CORBA::release (this->u_." << ub->local_name () << "_);" << be_nl; *os << "this->u_." << ub->local_name () - << "_ = 0;" << be_nl - << "break;" << be_uidt; + << "_ = 0;" << be_nl; break; case AST_PredefinedType::PT_any: *os << "delete this->u_." << ub->local_name () << "_;" << be_nl << "this->u_." << ub->local_name () - << "_ = 0;" << be_nl - << "break;" << be_uidt; + << "_ = 0;" << be_nl; break; case AST_PredefinedType::PT_void: break; default: - *os << "break;" << be_uidt; - break; } @@ -397,8 +405,7 @@ be_visitor_union_branch_public_reset_cs::visit_sequence ( << ub->local_name () << "_;" << be_nl << "this->u_." << ub->local_name () - << "_ = 0;" << be_nl - << "break;" << be_uidt; + << "_ = 0;" << be_nl; return 0; } @@ -435,8 +442,7 @@ be_visitor_union_branch_public_reset_cs::visit_string ( *os << ub->local_name () << "_);" << be_nl << "this->u_." << ub->local_name () - << "_ = 0;" << be_nl - << "break;" << be_uidt; + << "_ = 0;" << be_nl; return 0; } @@ -481,8 +487,6 @@ be_visitor_union_branch_public_reset_cs::visit_structure ( << "_ = 0;" << be_nl; } - *os << "break;" << be_uidt; - return 0; } @@ -540,8 +544,7 @@ be_visitor_union_branch_public_reset_cs::visit_union ( *os << "delete this->u_." << ub->local_name () << "_;" << be_nl << "this->u_." - << ub->local_name () << "_ = 0;" << be_nl - << "break;" << be_uidt; + << ub->local_name () << "_ = 0;" << be_nl; return 0; } diff --git a/TAO/TAO_IDL/be_include/be_visitor_union/cdr_op_cs.h b/TAO/TAO_IDL/be_include/be_visitor_union/cdr_op_cs.h index ed9a0089be9..9ce9d00c75e 100644 --- a/TAO/TAO_IDL/be_include/be_visitor_union/cdr_op_cs.h +++ b/TAO/TAO_IDL/be_include/be_visitor_union/cdr_op_cs.h @@ -39,6 +39,9 @@ public: virtual int pre_process (be_decl *); virtual int post_process (be_decl *); + +private: + BoolUnionBranch latest_branch_; }; #endif /* _BE_VISITOR_UNION_CDR_OP_CS_H_ */ diff --git a/TAO/TAO_IDL/be_include/be_visitor_union/union.h b/TAO/TAO_IDL/be_include/be_visitor_union/union.h index 58720b936f8..c854e6e2e73 100644 --- a/TAO/TAO_IDL/be_include/be_visitor_union/union.h +++ b/TAO/TAO_IDL/be_include/be_visitor_union/union.h @@ -38,6 +38,10 @@ public: /// visit union_branch virtual int visit_union_branch (be_union_branch *node); + + enum BoolUnionBranch { BUB_NONE, BUB_UNCONDITIONAL, BUB_TRUE, BUB_FALSE }; + + static BoolUnionBranch boolean_branch (be_union_branch *b); }; #endif /* _BE_VISITOR_UNION_UNION_H_ */ diff --git a/TAO/tests/IDL_Test/interface.idl b/TAO/tests/IDL_Test/interface.idl index fa2384d0720..6ff89c19f4a 100644 --- a/TAO/tests/IDL_Test/interface.idl +++ b/TAO/tests/IDL_Test/interface.idl @@ -168,7 +168,7 @@ local interface testlocal }; interface A { - union U switch(boolean) + union U switch (Bool) { case TRUE: A aa; }; diff --git a/TAO/tests/IDL_Test/union.idl b/TAO/tests/IDL_Test/union.idl index 897b41480df..712e7f29898 100644 --- a/TAO/tests/IDL_Test/union.idl +++ b/TAO/tests/IDL_Test/union.idl @@ -81,6 +81,25 @@ module UnionDiscTest }; }; +module AllBoolUnions +{ + union OneBranchT switch (boolean) { case TRUE: octet val; }; + union OneBranchF switch (boolean) { case FALSE: octet val; }; + union OneBranchD switch (boolean) { default: octet val; }; + union OneBranchTF switch (boolean) { case TRUE: case FALSE: octet val; }; + union OneBranchFT switch (boolean) { case FALSE: case TRUE: octet val; }; + union OneBranchTD switch (boolean) { case TRUE: default: octet val; }; + union OneBranchDT switch (boolean) { default: case TRUE: octet val; }; + union OneBranchFD switch (boolean) { case FALSE: default : octet val; }; + union OneBranchDF switch (boolean) { default: case FALSE: octet val; }; + union TwoBranchesTF switch (boolean) { case TRUE: octet val1; case FALSE: char val2; }; + union TwoBranchesFT switch (boolean) { case FALSE: octet val1; case TRUE: char val2; }; + union TwoBranchesTD switch (boolean) { case TRUE: octet val1; default: char val2; }; + union TwoBranchesDT switch (boolean) { default: octet val1; case TRUE: char val2; }; + union TwoBranchesFD switch (boolean) { case FALSE: octet val1; default: char val2; }; + union TwoBranchesDF switch (boolean) { default: octet val1; case FALSE: char val2; }; +}; + // Nested unions enum disc1 |