// Visit the Union_cs node and its scope. int be_visitor_union_cs::visit_union (be_union *node) { if (node->cli_stub_gen () || node->imported ()) { return 0; } TAO_OutStream *os = this->ctx_->stream (); be_visitor_context ctx (*this->ctx_); // The discriminant type may have to be defined here if it was an enum // declaration inside of the union statement. We need to generate its // typecode. be_type *bt = be_type::narrow_from_decl (node->disc_type ()); if (!bt) { ACE_ERROR_RETURN ((LM_ERROR, "(%N:%l) be_visitor_union_cs::" "visit_union - " "bad discriminant type\n"), -1); } be_visitor_union_discriminant_cs disc_visitor (&ctx); if (bt->accept (&disc_visitor) == -1) { ACE_ERROR_RETURN ((LM_ERROR, "(%N:%l) be_visitor_union_cs::" "visit union - " "codegen for discrminant failed\n"), -1); } // First generate code for any of the members (if required, e.g., // anonymous sequences, structs, unions, arrays). this->ctx_->state (TAO_CodeGen::TAO_UNION_PUBLIC_CS); if (this->visit_scope (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, "(%N:%l) be_visitor_union_cs" "visit_union - " "codegen for scope failed\n"), -1); } // Now generate the operations on the union such as the copy constructor // and the assignment operator. *os << be_nl_2 << "// TAO_IDL - Generated from" << be_nl << "// " << __FILE__ << ":" << __LINE__; // Generate the copy constructor and the assignment operator here. *os << be_nl_2 << node->name () << "::" << node->local_name () << " (void)" << be_nl << "{" << be_idt_nl << "ACE_OS::memset (&this->u_, 0, sizeof (this->u_));" << be_nl; // The default constructor must initialize the discriminator // to the first case label value found in the union declaration // so that, if the uninitialized union is inserted into an Any, // the Any destructor's call to deep_free() will work properly. *os << "this->disc_ = "; UTL_ScopeActiveIterator si (node, UTL_Scope::IK_decls); be_union_branch *ub = 0; // In case we have some bogus enum values from an enum declared // in our scope. while (ub == 0) { // Just get the union's first member. AST_Decl *d = si.item (); ub = be_union_branch::narrow_from_decl (d); si.next (); } // Get the first label in its list. AST_UnionLabel *ul = ub->label (0); AST_Union::DefaultValue dv; // This can indicate an error in the return value, but it is // caught elsewhere. (void) node->default_value (dv); bool test = dv.computed_ == 0 && ul->label_kind () == AST_UnionLabel::UL_label; if (test) { ub->gen_label_value (os); } else { ub->gen_default_label_value (os, node); } *os << ";"; if (dv.computed_ == 0) { *os << be_nl; be_visitor_union_branch_public_constructor_cs const_visitor (this->ctx_); if (ub->accept (&const_visitor) == -1) { ACE_ERROR_RETURN ((LM_ERROR, "(%N:%l) be_visitor_union_cs::" "visit union - " "codegen for constructor failed\n"), -1); } } *os << be_uidt_nl << "}" << be_nl_2; this->ctx_->state (TAO_CodeGen::TAO_UNION_PUBLIC_ASSIGN_CS); // So we know we are generating the copy constructor. this->ctx_->sub_state (TAO_CodeGen::TAO_UNION_COPY_CONSTRUCTOR); *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 (this->visit_scope (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, "(%N:%l) be_visitor_union_cs" "visit_union - " "codegen for copy ctor failed\n"), -1); } // If there is no explicit default case, but there // is an implicit one, and the discriminant is an enum, // we need this to avert warnings in some compilers that // 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 ()) { *os << be_nl << "default:" << be_nl << "break;"; } *os << be_uidt_nl << "}" << be_uidt_nl << "}" << be_nl_2; *os << node->name () << "::~" << node->local_name () << " (void)" << be_nl << "{" << be_idt_nl << "// Finalize." << be_nl << "this->_reset ();" << be_uidt_nl << "}" << be_nl_2; if (be_global->any_support ()) { *os << "void " << node->name () << "::_tao_any_destructor (void *_tao_void_pointer)" << be_nl << "{" << be_idt_nl << node->local_name () << " *tmp =" << be_idt_nl << "static_cast<" << node->local_name () << " *> (_tao_void_pointer);" << be_uidt_nl << "delete tmp;" << be_uidt_nl << "}" << be_nl_2; } this->ctx_->state (TAO_CodeGen::TAO_UNION_PUBLIC_ASSIGN_CS); // Reset this for generating the assignment operator. this->ctx_->sub_state (TAO_CodeGen::TAO_SUB_STATE_UNKNOWN); // Assignment operator. *os << node->name () << " &" << be_nl; *os << node->name () << "::operator= (const ::" << node->name () << " &u)" << be_nl; *os << "{" << be_idt_nl; // First check for self-assignment. *os << "if (&u == this)" << be_idt_nl << "{" << be_idt_nl << "return *this;" << be_uidt_nl << "}" << be_uidt_nl << be_nl; // Reset and set the discriminant. *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 (this->visit_scope (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, "(%N:%l) be_visitor_union_cs" "visit_union - " "codegen for assign op failed\n"), -1); } // If there is no explicit default case, but there // is an implicit one, and the discriminant is an enum, // we need this to avert warnings in some compilers that // 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 ()) { *os << be_nl << "default:" << be_nl << "break;"; } *os << be_uidt_nl << "}" << be_nl_2; *os << "return *this;" << be_uidt_nl; *os << "}" << be_nl_2; // The reset method. this->ctx_->state (TAO_CodeGen::TAO_UNION_PUBLIC_RESET_CS); *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 (this->visit_scope (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, "(%N:%l) be_visitor_union_cs" "visit_union - " "codegen for reset failed\n"), -1); } // If there is no explicit default case, but there // is an implicit one, and the discriminant is an enum, // we need this to avert warnings in some compilers that // 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 ()) { *os << be_nl << "default:" << be_nl << "break;"; } *os << be_uidt_nl << "}" << be_uidt_nl << "}"; if (be_global->tc_support ()) { ctx = *this->ctx_; // ctx.sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE); TAO::be_visitor_union_typecode tc_visitor (&ctx); if (tc_visitor.visit_union (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, "(%N:%l) be_visitor_union_cs::" "visit_union - " "TypeCode definition failed\n"), -1); } } node->cli_stub_gen (true); return 0; }
int be_visitor_interface_cs::visit_interface (be_interface *node) { if (node->imported () || node->cli_stub_gen ()) { return 0; } be_type *bt = 0; // Set the right type. if (this->ctx_->alias ()) { bt = this->ctx_->alias (); } else { bt = node; } AST_Component *c = AST_Component::narrow_from_decl (node); TAO_OutStream *os = this->ctx_->stream (); if (node->is_defined () && be_global->gen_arg_traits ()) { *os << be_nl_2 << "// TAO_IDL - Generated from" << be_nl << "// " << __FILE__ << ":" << __LINE__; *os << be_nl_2 << "// Traits specializations for " << node->name () << "."; *os << be_nl_2 << node->name () << "_ptr" << be_nl << "TAO::Objref_Traits<" << node->name () << ">::duplicate (" << be_idt << be_idt_nl << node->name () << "_ptr p)" << be_uidt << be_uidt_nl << "{" << be_idt_nl << "return " << node->name () << "::_duplicate (p);" << be_uidt_nl << "}"; *os << be_nl_2 << "void" << be_nl << "TAO::Objref_Traits<" << node->name () << ">::release (" << be_idt << be_idt_nl << node->name () << "_ptr p)" << be_uidt << be_uidt_nl << "{" << be_idt_nl; // Workaround for broken HP V7.4-004 on OpenVMS IA83 if (node->has_mixed_parentage ()) { *os << "::CORBA::AbstractBase_ptr abs = p;" << be_nl << "::CORBA::release (abs);" << be_uidt_nl; } else { *os << "::CORBA::release (p);" << be_uidt_nl; } *os << "}"; *os << be_nl_2 << node->name () << "_ptr" << be_nl << "TAO::Objref_Traits<" << node->name () << ">::nil (void)" << be_nl << "{" << be_idt_nl << "return " << node->name () << "::_nil ();" << be_uidt_nl << "}"; *os << be_nl_2 << "::CORBA::Boolean" << be_nl << "TAO::Objref_Traits<" << node->name () << ">::marshal (" << be_idt << be_idt_nl << "const " << node->name () << "_ptr p," << be_nl << "TAO_OutputCDR & cdr)" << be_uidt << be_uidt_nl << "{" << be_idt_nl << "return "; if (node->is_abstract () || c != 0) { *os << "cdr << p;"; } else { *os << "::CORBA::Object::marshal (p, cdr);"; } *os << be_uidt_nl << "}"; } // If we are generating CORBA Policy we need to add some more methods if (ACE_OS::strcmp (node->full_name (), "CORBA::Policy") == 0) { *os << be_nl << "CORBA::Boolean" << be_nl << "CORBA::Policy::_tao_encode (TAO_OutputCDR &)" << be_nl << "{" << be_nl << " return false;" << be_nl << "}" << be_nl << be_nl << "CORBA::Boolean" << be_nl << "CORBA::Policy::_tao_decode (TAO_InputCDR &)" << be_nl << "{" << be_nl << " return false;" << be_nl << "}" << be_nl << be_nl << "TAO_Cached_Policy_Type" << be_nl << "CORBA::Policy::_tao_cached_type (void) const" << be_nl << "{" << be_nl << "return TAO_CACHED_POLICY_UNCACHED;" << be_nl << "}" << be_nl << be_nl << "TAO_Policy_Scope" << be_nl << "CORBA::Policy::_tao_scope (void) const" << be_nl << "{" << be_nl << " return TAO_POLICY_DEFAULT_SCOPE;" << be_nl << "}" << be_nl; } if (be_global->gen_ostream_operators ()) { *os << be_nl_2 << "std::ostream &" << be_nl << node->name () << "::_tao_stream_v (std::ostream &strm) const" << be_nl << "{" << be_idt_nl << "return strm << \"\\\"" << node->repoID () << "\\\"\";" << be_uidt_nl << "}"; } if (node->has_mixed_parentage ()) { *os << be_nl_2 << "void" << be_nl << "CORBA::release (" << node->name () << "_ptr p)" << be_nl << "{" << be_idt_nl << "::CORBA::AbstractBase_ptr abs = p;" << be_nl << "::CORBA::release (abs);" << be_uidt_nl << "}"; *os << be_nl_2 << "::CORBA::Boolean" << be_nl << "CORBA::is_nil (" << node->name () << "_ptr p)" << be_nl << "{" << be_idt_nl << "::CORBA::Object_ptr obj = p;" << be_nl << "return ::CORBA::is_nil (obj);" << be_uidt_nl << "}"; } // Generate code for the elements of the interface. if (this->visit_scope (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_interface_cs::") ACE_TEXT ("visit_interface - ") ACE_TEXT ("codegen for scope failed\n")), -1); } if (node->is_local ()) { *os << be_nl_2 << node->name () << "::" << node->local_name () << " (void)" << be_nl << "{}"; } if (! node->is_abstract () && ! node->is_local ()) { *os << be_nl_2 << node->name () << "::" << node->local_name () << " (void)" << be_nl; *os << "{" << be_nl; *os << "}"; } *os << be_nl_2 << node->name () << "::~" << node->local_name () << " (void)" << be_nl; *os << "{" << be_nl << "}" << be_nl_2; bool gen_any_destructor = be_global->any_support () && (!node->is_local () || be_global->gen_local_iface_anyops ()); if (gen_any_destructor) { *os << "void" << be_nl << node->name () << "::_tao_any_destructor (void *_tao_void_pointer)" << be_nl << "{" << be_idt_nl << node->local_name () << " *_tao_tmp_pointer =" << be_idt_nl << "static_cast<" << node->local_name () << " *> (_tao_void_pointer);" << be_uidt_nl << "::CORBA::release (_tao_tmp_pointer);" << be_uidt_nl << "}" << be_nl_2; } if (node->has_mixed_parentage ()) { *os << "void" << be_nl << node->name () << "::_add_ref (void)" << be_nl << "{" << be_idt_nl << "this->::CORBA::Object::_add_ref ();" << be_uidt_nl << "}" << be_nl_2; } // The _narrow method if (! this->gen_xxx_narrow ("narrow", node)) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_interface_cs::") ACE_TEXT ("visit_interface - ") ACE_TEXT ("_narrow () method codegen failed\n")), -1); } // The _unchecked_narrow method, not for components. if (c == 0 && ! this->gen_xxx_narrow ("unchecked_narrow", node)) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_interface_cs::") ACE_TEXT ("visit_interface - ") ACE_TEXT ("_unchecked_narrow () method codegen") ACE_TEXT (" failed\n")), -1); } // The _nil method *os << node->full_name () << "_ptr" << be_nl << node->full_name () << "::_nil (void)" << be_nl << "{" << be_idt_nl << "return 0;" << be_uidt_nl << "}" << be_nl_2; // The _duplicate method *os << node->full_name () << "_ptr" << be_nl << node->full_name () << "::_duplicate (" << bt->local_name () << "_ptr obj)" << be_nl << "{" << be_idt_nl << "if (! ::CORBA::is_nil (obj))" << be_idt_nl << "{" << be_idt_nl << "obj->_add_ref ();" << be_uidt_nl << "}" << be_uidt_nl << "return obj;" << be_uidt_nl << "}" << be_nl_2; // The _tao_release method if (c == 0) { *os << "void" << be_nl << node->full_name () << "::_tao_release (" << bt->local_name () << "_ptr obj)" << be_nl << "{" << be_idt_nl << "::CORBA::release (obj);" << be_uidt_nl << "}" << be_nl_2; } *os << "::CORBA::Boolean" << be_nl << node->full_name () << "::_is_a (const char *value)" << be_nl; *os << "{" << be_idt_nl << "if (" << be_idt << be_idt_nl; int status = node->gen_is_a_ancestors (os); if (status == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_interface_cs::") ACE_TEXT ("visit_interface - ") ACE_TEXT ("gen_is_a_ancestors() failed\n")), -1); } *os << ")" << be_nl << "{" << be_idt_nl << "return true; // success using local knowledge" << be_uidt_nl << "}" << be_uidt_nl << "else" << be_idt_nl << "{" << be_idt_nl; if (node->is_abstract () || node->is_local ()) { *os << "return false;" << be_uidt_nl; } else { *os << "return this->::CORBA::Object::_is_a (value);" << be_uidt_nl; } *os << "}" << be_uidt << be_uidt_nl << "}" << be_nl_2; *os << "const char* " << node->full_name () << "::_interface_repository_id (void) const" << be_nl << "{" << be_idt_nl << "return \"" << node->repoID () << "\";" << be_uidt_nl << "}"; bool is_loc = node->is_local (); *os << be_nl_2 << "::CORBA::Boolean" << be_nl << node->name () << "::marshal (TAO_OutputCDR &" << (is_loc ? " /* " : "") << "cdr" << (is_loc ? " */" : "") << ")" << be_nl << "{" << be_idt_nl << "return " << (is_loc ? "false" : "(cdr << this)") << ";" << be_uidt_nl << "}"; if (! node->is_abstract ()) { // Smart Proxy classes. if (! node->is_local () && be_global->gen_smart_proxies ()) { be_visitor_context ctx (*this->ctx_); ctx.state (TAO_CodeGen::TAO_INTERFACE_SMART_PROXY_CS); be_visitor_interface_smart_proxy_cs isp_visitor (&ctx); if (node->accept (&isp_visitor) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_interface_cs::") ACE_TEXT ("visit_interface - ") ACE_TEXT ("codegen for smart ") ACE_TEXT ("proxy classes failed\n")), -1); } } } if (be_global->tc_support ()) { be_visitor_context ctx = *this->ctx_; TAO::be_visitor_objref_typecode tc_visitor (&ctx); if (node->accept (&tc_visitor) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_interface_cs::") ACE_TEXT ("visit_interface - ") ACE_TEXT ("TypeCode definition failed\n")), -1); } } return 0; }
int be_visitor_valuetype_cs::visit_valuetype (be_valuetype *node) { if (node->cli_stub_gen () || node->imported ()) { return 0; } if (be_global->tc_support ()) { be_visitor_context ctx (*this->ctx_); TAO::be_visitor_value_typecode tc_visitor (&ctx); if (tc_visitor.visit_valuetype (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, "(%N:%l) be_visitor_valuetype_cs::" "visit_valuetype - " "TypeCode definition failed\n"), -1); } } TAO_OutStream *os = this->ctx_->stream (); *os << be_nl_2 << "// TAO_IDL - Generated from" << be_nl << "// " << __FILE__ << ":" << __LINE__; if (node->is_defined ()) { *os << be_nl_2 << "void" << be_nl << "TAO::Value_Traits<" << node->name () << ">::add_ref (" << be_idt << be_idt_nl << node->name () << " * p)" << be_uidt << be_uidt_nl << "{" << be_idt_nl << "::CORBA::add_ref (p);" << be_uidt_nl << "}"; *os << be_nl_2 << "void" << be_nl << "TAO::Value_Traits<" << node->name () << ">::remove_ref (" << be_idt << be_idt_nl << node->name () << " * p)" << be_uidt << be_uidt_nl << "{" << be_idt_nl << "::CORBA::remove_ref (p);" << be_uidt_nl << "}"; *os << be_nl_2 << "void" << be_nl << "TAO::Value_Traits<" << node->name () << ">::release (" << be_idt << be_idt_nl << node->name () << " * p)" << be_uidt << be_uidt_nl << "{" << be_idt_nl << "::CORBA::remove_ref (p);" << be_uidt_nl << "}"; } // The _downcast method. *os << be_nl_2 << node->name () << " *" << be_nl << node->name () << "::_downcast ( ::CORBA::ValueBase *v)" << be_nl << "{" << be_idt_nl << "return dynamic_cast< ::" << node->name () << " * > (v);" << be_uidt_nl << "}" << be_nl_2; // The _tao_obv_repository_id method. *os << "const char *" << be_nl << node->name () << "::_tao_obv_repository_id (void) const" << be_nl << "{" << be_idt_nl << "return this->_tao_obv_static_repository_id ();" << be_uidt_nl << "}" << be_nl_2; *os << "void" << be_nl << node->name () << "::_tao_obv_truncatable_repo_ids (Repository_Id_List& ids) const" << be_nl << "{" << be_idt_nl << "ids.push_back (this->_tao_obv_static_repository_id ());"; if (node->truncatable ()) { *os << be_nl << node->inherits_concrete ()->name () << "::_tao_obv_truncatable_repo_ids (ids);" << be_uidt_nl << "}" << be_nl_2; } else { *os << be_uidt_nl << "}" << be_nl_2; } if (be_global->any_support ()) { *os << "void" << be_nl << node->name () << "::_tao_any_destructor (void *_tao_void_pointer)" << be_nl << "{" << be_idt_nl << node->local_name () << " *_tao_tmp_pointer =" << be_idt_nl << "static_cast<" << be_idt << node->local_name () << " *> (" << "_tao_void_pointer);" << be_uidt << be_uidt_nl << "::CORBA::remove_ref (_tao_tmp_pointer);" << be_uidt_nl << "}" << be_nl_2; } // Switch streams to the *A.cpp file if we are using this option. if (be_global->gen_anyop_files ()) { os = tao_cg->anyop_source (); } if (be_global->tc_support ()) { *os << "// TAO extension - the virtual _type method." << be_nl; *os << "::CORBA::TypeCode_ptr " << node->name () << "::_tao_type (void) const" << be_nl; *os << "{" << be_idt_nl; *os << "return ::" << node->tc_name () << ";" << be_uidt_nl; *os << "}" << be_nl_2; } // Make sure we are generating to *C.cpp regardless of the above. os = tao_cg->client_stubs (); // Generate destructor. // // @@ Do not inline this destructor. It is virtual. Inlining // virtual functions, including virtual destructors, wreaks havoc // with g++ >= 4.0 RTTI support when the // "-fvisibility-inlines-hidden" command line option is used. *os << node->name () << "::~" << node->local_name () << " (void)" << be_nl << "{}" << be_nl_2; bool is_an_amh_exception_holder = this->is_amh_exception_holder (node); // Nothing to marshal if abstract valuetype. if (!node->is_abstract () && !is_an_amh_exception_holder) { // The virtual _tao_marshal_v method. *os << "::CORBA::Boolean" << be_nl << node->name () << "::_tao_marshal_v (TAO_OutputCDR & strm) const" << be_nl << "{" << be_idt_nl << "TAO_ChunkInfo ci (this->is_truncatable_ || this->chunking_);" << be_nl << "return "; if (node->opt_accessor ()) { be_decl *scope = be_scope::narrow_from_scope (node->defined_in ())->decl (); *os << scope->name () << "::" << node->local_name () << "::_tao_marshal_state (strm, ci);" << be_uidt_nl; } else { *os << "this->_tao_marshal__" << node->flat_name () << " (strm, ci);" << be_uidt_nl; } *os << "}" << be_nl_2; // The virtual _tao_unmarshal_v method. *os << "::CORBA::Boolean" << be_nl << node->name () << "::_tao_unmarshal_v (TAO_InputCDR & strm)" << be_nl << "{" << be_idt_nl << "TAO_ChunkInfo ci (this->is_truncatable_ || this->chunking_, 1);" << be_nl << "return "; if (node->opt_accessor ()) { be_decl *scope = be_scope::narrow_from_scope (node->defined_in ())->decl (); *os << scope->name () << "::" << node->local_name () <<"::_tao_unmarshal_state (strm,ci);" << be_uidt_nl; } else { *os << "this->_tao_unmarshal__" << node->flat_name () << " (strm,ci);" << be_uidt_nl; } *os << "}" << be_nl_2; *os << "::CORBA::Boolean" << be_nl << node->name () << "::_tao_match_formal_type (ptrdiff_t formal_type_id) const" << be_nl << "{" << be_idt_nl << "return formal_type_id == reinterpret_cast<ptrdiff_t> (" << node->name() << "::_downcast);" << be_uidt_nl << "}" << be_nl_2; } else if (is_an_amh_exception_holder) { // @@ Do not inline. They're virtual. Inlining virtual // functions, including virtual destructors, wreaks havoc with // g++ >= 4.0 RTTI support when the // "-fvisibility-inlines-hidden" command line option is used. // The virtual _copy_value method. *os << "::CORBA::ValueBase *" << be_nl << node->name () << "::_copy_value (void)" << be_nl << "{" << be_idt_nl << "::CORBA::ValueBase *ret_val = 0;" << be_nl << "ACE_NEW_THROW_EX (" << be_idt_nl << "ret_val," << be_nl << node->local_name () << " ()," << be_nl << "::CORBA::NO_MEMORY ()" << be_uidt_nl << ");" << be_nl << "return ret_val;" << be_uidt_nl << "}" << be_nl_2; // The virtual _tao_marshal_v method. *os << "::CORBA::Boolean" << be_nl << node->name () << "::_tao_marshal_v (TAO_OutputCDR &) const" << be_nl << "{" << be_idt_nl << "return true;" << be_uidt_nl << "}" << be_nl_2; // The virtual _tao_unmarshal_v method. *os << "::CORBA::Boolean" << be_nl << node->name () << "::_tao_unmarshal_v (TAO_InputCDR &)" << be_nl << "{" << be_idt_nl << "return true;" << be_uidt_nl << "}" << be_nl_2; // The virtual _tao_match_formal_type method. *os << "::CORBA::Boolean" << be_nl << node->name () << "::_tao_match_formal_type (ptrdiff_t ) const" << be_nl << "{" << be_idt_nl << "return false;"<< be_uidt_nl << "}" << be_nl_2; if (!node->opt_accessor () && !node->is_abstract ()) { *os << "::CORBA::Boolean" << be_nl << node->name () << "::_tao_marshal__" << node->flat_name () << " (TAO_OutputCDR &, TAO_ChunkInfo&) const" << be_nl << "{" << be_idt_nl << "return true;" << be_uidt_nl << "}" << be_nl_2; *os << "::CORBA::Boolean" << be_nl << node->name () << "::_tao_unmarshal__" << node->flat_name () << " (TAO_InputCDR &, TAO_ChunkInfo&)" << be_nl << "{" << be_idt_nl << "return true;" << be_uidt_nl << "}" << be_nl_2; } } if (be_global->gen_ostream_operators ()) { *os << "std::ostream &" << be_nl << node->name () << "::_tao_stream_v (std::ostream &strm) const" << be_nl << "{" << be_idt_nl << "strm << \"" << node->name () << "(\""; unsigned long index = 0; this->gen_ostream_operator_r (node, index); *os << be_nl << " << \")\";" << be_nl_2 << "return strm;" << be_uidt_nl << "}" << be_nl_2; } // The static T::_tao_unmarshal method *os << "::CORBA::Boolean" << be_nl << node->name() << "::_tao_unmarshal (" << be_idt << be_idt_nl << "TAO_InputCDR &strm," << be_nl << node->local_name () << " *&new_object" << be_uidt_nl << ")" << be_uidt_nl << "{" << be_idt_nl << "::CORBA::ValueBase *base = 0;" << be_nl << "::CORBA::Boolean is_indirected = false;" << be_nl << "::CORBA::Boolean is_null_object = false;" << be_nl << "::CORBA::Boolean const retval =" << be_idt_nl << "::CORBA::ValueBase::_tao_unmarshal_pre (" << be_idt << be_idt_nl << "strm," << be_nl << "base," << be_nl << node->local_name () << "::_tao_obv_static_repository_id ()," << be_nl << "is_null_object," << be_nl << "is_indirected" << be_uidt_nl << ");" << be_uidt << be_uidt_nl << be_nl << "::CORBA::ValueBase_var owner (base);" << be_nl_2 << "if (!retval)" << be_idt_nl << "return false;" << be_uidt_nl << be_nl << "if (is_null_object)" << be_idt_nl << "return true;" << be_uidt_nl << be_nl << "if (!is_indirected && !base->_tao_unmarshal_v (strm))" << be_idt_nl << "return false;" << be_uidt_nl << be_nl << "// Now base must point to the unmarshaled object." << be_nl << "// Align the pointer to the right subobject." << be_nl << "new_object = " << node->local_name () << "::_downcast (base);" << be_nl << "if (0 == new_object)" << be_idt_nl << "return false;" << be_uidt_nl << be_nl << "if (is_indirected)" << be_idt_nl << "new_object->_add_ref ();" << be_uidt_nl << be_nl << "owner._retn ();" << be_nl << "return true;" << be_uidt_nl << "}"; // If we inherit from CORBA::Object and/or CORBA::AbstractBase // (in addition to CORBA::ValueBase) we have to add these // to avoid ambiguity. if (node->n_supports () > 0) { *os << be_nl_2 << "::CORBA::ValueBase *" << be_nl << node->name () << "::_tao_to_value (void)" << be_nl << "{" << be_idt_nl << "return this;" << be_uidt_nl << "}"; } // Generate code for the elements of the valuetype. if (this->visit_scope (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, "(%N:%l) be_visitor_valuetype_cs::" "visit_valuetype - " "codegen for scope failed\n"), -1); } // Generate the _init-related code. be_visitor_context ctx (*this->ctx_); be_visitor_valuetype_init_cs vi_visitor (&ctx); if (vi_visitor.visit_valuetype (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, "(%N:%l) be_visitor_valuetype_ch::" "visit_valuetype - " "failed to generate _init construct.\n"), -1); } return 0; }
int be_visitor_union_ch::visit_union (be_union *node) { if (node->cli_hdr_gen () || node->imported ()) { return 0; } // Evaluate the member in time for the decision to generate // the recursive typecode include in the stub source file. ACE_Unbounded_Queue<AST_Type *> list; (void) node->in_recursion (list); // Instantiate a visitor context with a copy of our context. This info // will be modified based on what type of node we are visiting. be_visitor_context ctx (*this->ctx_); ctx.node (node); TAO_OutStream *os = this->ctx_->stream (); // Generate _var and _out class typedefs. node->gen_common_varout (os); *os << be_nl_2 << "class " << be_global->stub_export_macro () << " " << node->local_name () << be_nl << "{" << be_nl << "public:" << be_idt_nl // Generate default and copy constructors. << node->local_name () << " (void);" << be_nl << node->local_name () << " (const " << node->local_name () << " &);" << be_nl // Generate destructor. << "~" << node->local_name () << " (void);"; // Generate assignment operator. *os << be_nl_2 << node->local_name () << " &operator= (const " << node->local_name () << " &);"; // Retrieve the disriminant type. be_type *bt = be_type::narrow_from_decl (node->disc_type ()); if (!bt) { ACE_ERROR_RETURN ((LM_ERROR, "(%N:%l) be_visitor_union_ch::" "visit_union - " "bad disciminant type\n"), -1); } // The discriminant type may have to be defined here if it was an enum // declaration inside of the union statement. be_visitor_union_discriminant_ch ud_visitor (&ctx); if (bt->accept (&ud_visitor) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_union_ch::") ACE_TEXT (" visit_union - ") ACE_TEXT ("codegen for discriminant failed\n")), -1); } node->gen_stub_decls (os); // Now generate the public defn for the union branch members. For this, // set our state to reflect what we are aiming to do. this->ctx_->state (TAO_CodeGen::TAO_UNION_PUBLIC_CH); if (this->visit_scope (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_union_ch::") ACE_TEXT ("visit_union - ") ACE_TEXT ("codegen for public ") ACE_TEXT ("defn of union members\n")), -1); } // Now check if we need to generate the _default () method. be_union::DefaultValue dv; if (node->default_value (dv) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_union_ch::") ACE_TEXT ("visit_union - ") ACE_TEXT ("computing default ") ACE_TEXT ("value failed\n")), -1); } if ((dv.computed_ != 0) && (node->default_index () == -1)) { *os << be_nl_2 << "// TAO_IDL - Generated from" << be_nl << "// " << __FILE__ << ":" << __LINE__; // Only if all cases are not covered AND there is no explicit // default, we get the _default () method. *os << be_nl_2 << "void _default (void);"; } *os << be_uidt_nl; // Now generate the private data members of the union. *os << "private:" << be_idt_nl; *os << bt->nested_type_name (node) << " disc_;" << be_nl_2; // The members are inside of a union. *os << "union" << be_nl; *os << "{" << be_idt; this->ctx_->state (TAO_CodeGen::TAO_UNION_PRIVATE_CH); if (this->visit_scope (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_union_ch::") ACE_TEXT ("visit_union - ") ACE_TEXT ("codegen for private") ACE_TEXT (" members of union\n")), -1); } *os << be_uidt_nl; *os << "} u_;"; // The reset method (TAO extension). *os << be_nl_2 << "/// TAO extension - frees any allocated storage." << be_nl; *os << "void _reset (void);"; *os << be_uidt_nl << "};"; if (be_global->tc_support ()) { ctx = *this->ctx_; be_visitor_typecode_decl tc_visitor (&ctx); if (node->accept (&tc_visitor) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_union_ch::") ACE_TEXT ("visit_union - ") ACE_TEXT ("TypeCode declaration failed\n")), -1); } } node->cli_hdr_gen (true); return 0; }