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 (); }
/* * 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; }
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; }
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])); } } }