示例#1
0
文件: fe_utils.cpp 项目: CCJY/ATCD
void
FE_Utils::create_uses_multiple_stuff (AST_Component *c,
                                      AST_Uses *u,
                                      const char *prefix)
{
  ACE_CString struct_name (prefix);

  if (!struct_name.empty ())
    {
      struct_name += '_';
    }

  struct_name += u->local_name ()->get_string ();
  struct_name += "Connection";
  Identifier struct_id (struct_name.c_str ());
  UTL_ScopedName sn (&struct_id, 0);

  // In case this call comes from the backend. We
  // will pop the scope before returning.
  idl_global->scopes ().push (c);

  AST_Structure *connection =
    idl_global->gen ()->create_structure (&sn, 0, 0);

  struct_id.destroy ();

  /// If the field type is a param holder, we want
  /// to use the lookup to create a fresh one,
  /// since the field will own it and destroy it.
  UTL_ScopedName *fn = u->uses_type ()->name ();
  AST_Decl *d =
    idl_global->root ()->lookup_by_name (fn, true, false);
  AST_Type *ft = AST_Type::narrow_from_decl (d);

  Identifier object_id ("objref");
  UTL_ScopedName object_name (&object_id,
                              0);
  AST_Field *object_field =
    idl_global->gen ()->create_field (ft,
                                      &object_name,
                                      AST_Field::vis_NA);
  (void) DeclAsScope (connection)->fe_add_field (object_field);
  object_id.destroy ();

  Identifier local_id ("Cookie");
  UTL_ScopedName local_name (&local_id,
                             0);
  Identifier module_id ("Components");
  UTL_ScopedName scoped_name (&module_id,
                              &local_name);

  d = c->lookup_by_name (&scoped_name, true);
  local_id.destroy ();
  module_id.destroy ();

  if (d == 0)
    {
      // This would happen if we haven't included Components.idl.
      idl_global->err ()->lookup_error (&scoped_name);
      return;
    }

  AST_ValueType *cookie = AST_ValueType::narrow_from_decl (d);

  Identifier cookie_id ("ck");
  UTL_ScopedName cookie_name (&cookie_id,
                              0);
  AST_Field *cookie_field =
    idl_global->gen ()->create_field (cookie,
                                      &cookie_name,
                                      AST_Field::vis_NA);
  (void) DeclAsScope (connection)->fe_add_field (cookie_field);
  cookie_id.destroy ();

  (void) c->fe_add_structure (connection);

  ACE_CDR::ULong bound = 0;
  AST_Expression *bound_expr =
    idl_global->gen ()->create_expr (bound,
                                     AST_Expression::EV_ulong);
  AST_Sequence *sequence =
    idl_global->gen ()->create_sequence (bound_expr,
                                         connection,
                                         0,
                                         0,
                                         0);

  ACE_CString seq_string (struct_name);
  seq_string += 's';
  Identifier seq_id (seq_string.c_str ());
  UTL_ScopedName seq_name (&seq_id,
                           0);
  AST_Typedef *connections =
    idl_global->gen ()->create_typedef (sequence,
                                        &seq_name,
                                        0,
                                        0);
  seq_id.destroy ();

  (void) c->fe_add_typedef (connections);

  // In case this call comes from the backend.
  idl_global->scopes ().pop ();
}
示例#2
0
/*
 * Helper function for lookup_by_name. Iterates doing local lookups of
 * subsequent components of a scoped name
 */
static AST_Decl *
iter_lookup_by_name_local(AST_Decl *d, UTL_ScopedName *e,
                          idl_bool treat_as_ref)
{
   Identifier *s;
   AST_Typedef *td;
   UTL_IdListActiveIterator *i;
   UTL_Scope *sc;

   i = new UTL_IdListActiveIterator(e);

   for (i->next(); !(i->is_done()); )
   {
      s = i->item();
      /*
       * Update iterator before loop. This is needed for the check for
       * typedef, since we only want to look at the base type if there
       * actually are more components of the name to resolve.
       */
      i->next();
      /*
       * Next component in name was not found
       */

      if (d == NULL)
      {
         return NULL;
      }

      /*
       * If this is a typedef and we're not done, we should get the
       * base type to get the scope it defines (if any)
       */
      if (!(i->is_done()))
      {
         while (d != NULL && d->node_type() == AST_Decl::NT_typedef)
         {
            td = AST_Typedef::narrow_from_decl(d);

            if (td == NULL)
               return NULL;

            d = td->base_type();
         }

         if (d == NULL)
            return NULL;
      }

      /*
       * Try to convert the AST_Decl to a UTL_Scope
       */
      sc = DeclAsScope(d);

      if (sc == NULL)
         return NULL;

      /*
       * Look up the next element
       */
      d = sc->lookup_by_name_local (s);
   }

   /*
    * OK, done with the loop
    */ 
   return d;
}
示例#3
0
int be_visitor_sequence_ch::visit_sequence (be_sequence *node)
{
  if (node->defined_in () == 0)
    {
      // The node is a nested sequence, and has had no scope defined.
      node->set_defined_in (DeclAsScope (this->ctx_->scope ()->decl ()));
    }

  // First create a name for ourselves.
  if (node->create_name (this->ctx_->tdef ()) == -1)
    {
      ACE_ERROR_RETURN ((LM_ERROR,
                         ACE_TEXT ("be_visitor_sequence_ch::")
                         ACE_TEXT ("visit_sequence - ")
                         ACE_TEXT ("failed creating name\n")),
                        -1);
    }

  // We don't check cli_hdr_gen() here. If we are generated more
  // than once as an anonymous sequence, the name guard will cause
  // the C++ preprocessor to catch it. If we are generated more than
  // once as a typedef (caused by a comma separated list of
  // typedefs), our name will be changed by the call above and the
  // name guard will not catch it, but that's ok - we want to
  // be generated for each typedef.
  if (node->imported ())
    {
      return 0;
    }

  TAO_OutStream *os = this->ctx_->stream ();

  // Retrieve the base type since we may need to do some code
  // generation for the base type.
  be_type *bt = be_type::narrow_from_decl (node->base_type ());

  if (bt == 0)
    {
      ACE_ERROR_RETURN ((LM_ERROR,
                         ACE_TEXT ("be_visitor_sequence_ch::")
                         ACE_TEXT ("visit_sequence - ")
                         ACE_TEXT ("Bad element type\n")),
                        -1);
    }

  bt->seen_in_sequence (true);
  AST_Decl::NodeType nt = bt->node_type ();

  // If our base type is an anonymous sequence, we must create a name
  // and generate a class declaration for it as well.
  if (nt == AST_Decl::NT_sequence)
    {
      // Temporarily make the context's tdef node 0 so the nested call
      // to create_name will not get confused and give our anonymous
      // sequence element type the same name as we have.
      be_typedef *tmp = this->ctx_->tdef ();
      this->ctx_->tdef (0);

      if (bt->accept (this) != 0)
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                             ACE_TEXT ("be_visitor_sequence_ch::")
                             ACE_TEXT ("visit_sequence - ")
                             ACE_TEXT ("codegen for anonymous ")
                             ACE_TEXT ("base type failed\n")),
                            -1);
        }

      // Restore the tdef value.
      this->ctx_->tdef (tmp);
    }

  *os << be_nl_2;

  *os << "// TAO_IDL - Generated from" << be_nl
      << "// " << __FILE__ << ":" << __LINE__;

  if (idl_global->dcps_sequence_type_defined (node->full_name ()))
    {
      // generate the sequence declaration as if it was native. This
      // to satisfy DDS

      // strip  the "Seq" ending to get the sample's name
      const char * node_name = node->full_name ();
      const size_t max_name_length = 2000;
      if (ACE_OS::strlen (node_name) >= max_name_length)
        {
          return -1;
        }
      char sample_name[max_name_length];
      ACE_OS::strncpy (sample_name,
                       node_name,
                       ACE_OS::strlen (node_name) - 3);
      sample_name[ACE_OS::strlen (node_name) - 3] = '\0';

      *os << be_nl_2
          << "typedef ::TAO::DCPS::ZeroCopyDataSeq< "
          << sample_name
          << ", DCPS_ZERO_COPY_SEQ_DEFAULT_SIZE> "
          << node->local_name ()
          << ";" << be_nl;
    }
  else
    {
      os->gen_ifdef_macro (node->flat_name ());

      *os << be_nl_2;

      /// If we are using std::vector, we won't be using _vars
      /// and _outs. They may get redefined and reinstated later.
      if (!be_global->alt_mapping () || !node->unbounded ())
        {
          if (this->ctx_->tdef () != 0)
            {
              *os << "class " << node->local_name () << ";";
            }

          if (this->ctx_->tdef () != 0)
            {
              this->gen_varout_typedefs (node, bt);
            }
        }
      else
        {
          *os << "typedef std::vector< ";

          // Generate the base type for the buffer.
          be_visitor_context ctx (*this->ctx_);
          ctx.state (TAO_CodeGen::TAO_SEQUENCE_BUFFER_TYPE_CH);
          be_visitor_sequence_buffer_type bt_visitor (&ctx);

          if (bt->accept (&bt_visitor) == -1)
            {
              ACE_ERROR_RETURN ((LM_ERROR,
                                ACE_TEXT ("be_visitor_sequence_ch::")
                                ACE_TEXT ("visit_sequence - ")
                                ACE_TEXT ("buffer type visit failed\n")),
                                -1);
            }

          *os << "> " << node->local_name () << ";";

          os->gen_endif ();
          node->cli_hdr_gen (true);
          return 0;
        }

      *os << be_nl_2
          << "class " << be_global->stub_export_macro () << " "
          << node->local_name () << be_idt_nl
          << ": public" << be_idt << be_idt_nl;

      int status =
        node->gen_base_class_name (os,
                                  "",
                                  this->ctx_->scope ()->decl ());

      if (status == -1)
        {
          ACE_ERROR_RETURN ((LM_ERROR,
                            ACE_TEXT ("be_visitor_sequence_ch::")
                            ACE_TEXT ("visit_sequence - ")
                            ACE_TEXT ("Base class name ")
                            ACE_TEXT ("generation failed\n")),
                            -1);
        }

      *os << be_uidt << be_uidt << be_uidt;

      *os << be_nl
          << "{" << be_nl
          << "public:" << be_idt;

      *os << be_nl
          << node->local_name () << " (void);";

      if (node->unbounded ())
        {
          *os << be_nl
              << node->local_name () << " ( ::CORBA::ULong max);";
        }

      /// If we are using std::vector, we can't implement this
      /// constructor.
      if (!be_global->alt_mapping () || !node->unbounded ())
        {
          *os << be_nl
              << node->local_name () << " (" << be_idt;

          if (node->unbounded ())
            {
              *os << be_nl
                  << "::CORBA::ULong max,";
            }

          *os << be_nl
              << "::CORBA::ULong length," << be_nl;

          // Generate the base type for the buffer.
          be_visitor_context ctx (*this->ctx_);
          ctx.state (TAO_CodeGen::TAO_SEQUENCE_BUFFER_TYPE_CH);
          be_visitor_sequence_buffer_type bt_visitor (&ctx);

          if (bt->accept (&bt_visitor) == -1)
            {
              ACE_ERROR_RETURN ((LM_ERROR,
                                ACE_TEXT ("be_visitor_sequence_ch::")
                                ACE_TEXT ("visit_sequence - ")
                                ACE_TEXT ("buffer type visit failed\n")),
                                -1);
            }

          *os << "* buffer," << be_nl
              << "::CORBA::Boolean release = false);" << be_uidt;
      }

      *os << be_nl
          << node->local_name () << " (const " << node->local_name ()
          << " &);" << be_nl;
      *os << "virtual ~" << node->local_name () << " (void);";

      if (be_global->alt_mapping () && node->unbounded ())
        {
          *os << be_nl_2
              << "virtual ::CORBA::ULong length (void) const;"
              << be_nl
              << "virtual void length ( ::CORBA::ULong);"
              << be_nl_2
              << "virtual ::CORBA::ULong maximum (void) const;";
        }

      *os << be_nl;

      node->gen_stub_decls (os);

      // TAO provides extensions for octet sequences, first find out if
      // the base type is an octet (or an alias for octet).
      be_predefined_type *predef = 0;

      if (bt->base_node_type () == AST_Type::NT_pre_defined)
        {
          be_typedef* alias =
                be_typedef::narrow_from_decl (bt);

          if (alias == 0)
            {
              predef = be_predefined_type::narrow_from_decl (bt);
            }
          else
            {
              predef =
                be_predefined_type::narrow_from_decl (
                    alias->primitive_base_type ()
                  );
            }
        }

      // Now generate the extension...
      if (predef != 0
          && predef->pt () == AST_PredefinedType::PT_octet
          && node->unbounded ()
          && !be_global->alt_mapping ())
        {
          *os << be_nl_2
              << "\n\n#if (TAO_NO_COPY_OCTET_SEQUENCES == 1)" << be_nl
              << node->local_name () << " (" << be_idt << be_idt_nl
              << "::CORBA::ULong length," << be_nl
              << "const ACE_Message_Block* mb" << be_uidt_nl
              << ")" << be_uidt_nl
              << "  : ::TAO::unbounded_value_sequence< ::CORBA::Octet>"
              << " (length, mb) {}" << "\n"
              << "#endif /* TAO_NO_COPY_OCTET_SEQUENCE == 1 */";
        }

      *os << be_uidt_nl
          << "};";

      os->gen_endif ();
    }

  node->cli_hdr_gen (true);
  return 0;
}
示例#4
0
void
be_component::scan (UTL_Scope *s)
{
  if (s == 0)
    {
      return;
    }

  AST_Extended_Port *ep = 0;
  AST_Mirror_Port *mp = 0;
  AST_Uses *u = 0;
  AST_Provides *p = 0;
  AST_Attribute *a = 0;
  AST_Decl::NodeType my_nt;
  AST_Decl::NodeType scope_nt;

  for (UTL_ScopeActiveIterator i (s, UTL_Scope::IK_both);
       !i.is_done ();
       i.next ())
    {
      AST_Decl *d = i.item ();

      switch (d->node_type ())
        {
          case AST_Decl::NT_provides:
            ++this->n_provides_;
            p = AST_Provides::narrow_from_decl (d);

            if (!p->provides_type ()->is_local ())
              {
                ++this->n_remote_provides_;
              }

            continue;
          case AST_Decl::NT_uses:
            ++this->n_uses_;
            u = AST_Uses::narrow_from_decl (d);

            if (u->is_multiple ())
              {
                this->has_uses_multiple_ = true;
              }

            if (!u->uses_type ()->is_local ())
              {
                ++this->n_remote_uses_;
              }

            continue;
          case AST_Decl::NT_publishes:
            ++this->n_publishes_;
            continue;
          case AST_Decl::NT_consumes:
            ++this->n_consumes_;
            continue;
          case AST_Decl::NT_emits:
            ++this->n_emits_;
            continue;
          case AST_Decl::NT_ext_port:
            ep = AST_Extended_Port::narrow_from_decl (d);
            this->scan (ep->port_type ());
            continue;
          case AST_Decl::NT_mirror_port:
            mp = AST_Mirror_Port::narrow_from_decl (d);
            this->mirror_scan (mp->port_type ());
            continue;
          case AST_Decl::NT_attr:
            a = AST_Attribute::narrow_from_decl (d);;

            if (!a->readonly ())
              {
                my_nt = this->node_type ();
                scope_nt =
                  ScopeAsDecl (a->defined_in ())->node_type ();

                /// Attributes coming from a porttype appear
                /// only on connectors.
                if (my_nt == AST_Decl::NT_component
                    && scope_nt == AST_Decl::NT_porttype)
                  {
                    continue;
                  }

                this->has_rw_attributes_ = true;
              }

            continue;
          default:
            continue;
        }
    }

  AST_Component *c = AST_Component::narrow_from_scope (s);
  AST_Interface *iface = 0;

  if (c != 0)
    {
      for (long i = 0; i < c->n_supports (); ++i)
        {
          // See if the supported interfaces (if any) have attributes.
          // If CORBA::Object is supported, DeclAsScope will evaluate
          // to 0 and the call to scan() will return immediately.
          this->scan (DeclAsScope (c->supports ()[i]));
        }

      // Check the base component. If there is none, the arg to scan()
      // will be 0 and the call will return immediately.
      this->scan (c->base_component ());
    }
  else if ((iface = AST_Interface::narrow_from_scope (s)) != 0)
    {
      for (long i = 0; i < iface->n_inherits (); ++i)
        {
          // Will pick up a chain of inheritance,
          // no need to use inherits_flat().
          this->scan (DeclAsScope (iface->inherits ()[i]));
        }
    }
}