Esempio n. 1
0
// 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;
}
Esempio n. 2
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;
}
Esempio n. 3
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;
}
Esempio n. 4
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;
}