/** * @file be_visitor_ccm_pre_proc.cpp * * @author Jeff Parsons */ //============================================================================= #include "be_visitor_ccm_pre_proc.h" #include "be_visitor_context.h" #include "be_visitor_xplicit_pre_proc.h" #include "be_root.h" #include "be_operation.h" #include "be_argument.h" #include "be_exception.h" #include "be_structure.h" #include "be_sequence.h" #include "be_valuetype.h" #include "be_module.h" #include "be_template_module.h" #include "be_template_module_inst.h" #include "be_field.h" #include "be_typedef.h" #include "be_connector.h" #include "be_provides.h" #include "be_uses.h" #include "be_publishes.h" #include "be_emits.h" #include "be_consumes.h" #include "be_extended_port.h" #include "be_porttype.h" #include "be_eventtype.h" #include "be_eventtype_fwd.h" #include "be_home.h" #include "be_finder.h" #include "be_extern.h" #include "ast_generator.h" #include "utl_exceptlist.h" #include "utl_namelist.h" #include "utl_err.h" #include "fe_interface_header.h" #include "global_extern.h" #include "nr_extern.h" const char *LW_EXCEP_NAMES[] = { "AlreadyConnected", "InvalidConnection", "NoConnection", "ExceededConnectionLimit", "CreateFailure", "RemoveFailure", "FinderFailure" }; const char *ADDL_EXCEP_NAMES[] = { "InvalidKey", "UnknownKeyValue", "DuplicateKeyValue" }; const int N_LW_EXCEPS = sizeof (LW_EXCEP_NAMES) / sizeof (char *); const int N_ADDL_EXCEPS = sizeof (ADDL_EXCEP_NAMES) / sizeof (char *); be_exception *LW_EXCEPS[N_LW_EXCEPS]; be_exception *ADDL_EXCEPS[N_ADDL_EXCEPS]; be_visitor_ccm_pre_proc::be_visitor_ccm_pre_proc ( be_visitor_context *ctx) : be_visitor_component_scope (ctx), module_id_ ("Components"), cookie_ (nullptr), already_connected_ (nullptr), invalid_connection_ (nullptr), no_connection_ (nullptr), exceeded_connection_limit_ (nullptr), create_failure_ (nullptr), remove_failure_ (nullptr), finder_failure_ (nullptr), invalid_key_ (nullptr), unknown_key_value_ (nullptr), duplicate_key_value_ (nullptr), comp_ (nullptr), home_ (nullptr), ccm_lookups_done_ (false) { } be_visitor_ccm_pre_proc::~be_visitor_ccm_pre_proc () { this->module_id_.destroy (); } int be_visitor_ccm_pre_proc::visit_root (be_root *node) { /// Do this before traversing the tree so the traversal /// will pick up the implied uses nodes we add, if any. /// No need to check for the -GM option here - what's /// generated by this call depends only on the contents /// of the ciao_ami_recep_names_ queue. int const status = this->generate_ami4ccm_uses (); if (status == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_root - ") ACE_TEXT ("generate_ami4ccm_uses() ") ACE_TEXT ("failed\n")), -1); } if (this->visit_scope (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_root - ") ACE_TEXT ("visit scope failed\n")), -1); } return 0; } int be_visitor_ccm_pre_proc::visit_module (be_module *node) { if (this->visit_scope (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_module - ") ACE_TEXT ("visit scope failed\n")), -1); } return 0; } int be_visitor_ccm_pre_proc::visit_component (be_component *node) { /// Waiting to do this until a component is seen will ensure /// that Components.idl is present and the lookups will /// succeed. The flag ensures that the lookup is done only /// once. if (!this->ccm_lookups_done_) { if (this->lookup_cookie () == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_root - ") ACE_TEXT ("Components::Cookie ") ACE_TEXT ("lookup failed\n")), -1); } if (this->lookup_exceptions () == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_root - ") ACE_TEXT ("component exception ") ACE_TEXT ("lookups failed\n")), -1); } this->ccm_lookups_done_ = true; } // Set working node for all port code generation. this->comp_ = node; if (this->visit_scope (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_component - ") ACE_TEXT ("code generation for ") ACE_TEXT ("scope3 failed\n")), -1); } return 0; } int be_visitor_ccm_pre_proc::visit_connector (be_connector *node) { return this->visit_component (node); } int be_visitor_ccm_pre_proc::visit_provides (be_provides *node) { if (node->provides_type ()->is_local ()) { return 0; } if (!be_global->gen_lwccm ()) { // If this facet comes from a porttype, the instantiated // port/mirrorport name is prefixed to the facet name. ACE_CString prefix ("provide_"); prefix += this->ctx_->port_prefix (); AST_Operation *provides_op = nullptr; UTL_ScopedName *op_name = this->create_scoped_name (prefix.c_str (), node->local_name ()->get_string (), nullptr, comp_); ACE_NEW_RETURN (provides_op, be_operation (node->provides_type (), AST_Operation::OP_noflags, nullptr, 0, 0), -1); provides_op->set_defined_in (comp_); provides_op->set_imported (comp_->imported ()); provides_op->set_name (op_name); if (nullptr == comp_->be_add_operation (provides_op)) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_provides - ") ACE_TEXT ("be_add_operation() failed\n")), -1); } } return 0; } int be_visitor_ccm_pre_proc::visit_uses (be_uses *node) { if (node->uses_type ()->is_local ()) { return 0; } if (!be_global->gen_lwccm ()) { if (node->is_multiple ()) { if (this->gen_connect_multiple (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_uses - ") ACE_TEXT ("gen_connect_multiple failed\n")), -1); } if (this->gen_disconnect_multiple (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_uses - ") ACE_TEXT ("gen_disconnect_multiple failed\n")), -1); } if (this->gen_get_connection_multiple (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_uses - ") ACE_TEXT ("gen_get_connection_single failed\n")), -1); } } else { if (this->gen_connect_single (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_uses - ") ACE_TEXT ("gen_connect_single failed\n")), -1); } if (this->gen_disconnect_single (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_uses - ") ACE_TEXT ("gen_disconnect_single failed\n")), -1); } if (this->gen_get_connection_single (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_uses - ") ACE_TEXT ("gen_get_connection_single failed\n")), -1); } } } return 0; } int be_visitor_ccm_pre_proc::visit_publishes (be_publishes *node) { if (!be_global->gen_noeventccm ()) { if (this->gen_subscribe (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_publishes - ") ACE_TEXT ("gen_subscribe failed\n")), -1); } if (this->gen_unsubscribe (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_publishes - ") ACE_TEXT ("gen_unsubscribe failed\n")), -1); } } return 0; } int be_visitor_ccm_pre_proc::visit_emits (be_emits *node) { if (!be_global->gen_noeventccm ()) { if (this->gen_emits_connect (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_emits - ") ACE_TEXT ("gen_emits_connect failed\n")), -1); } if (this->gen_emits_disconnect (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_emits - ") ACE_TEXT ("gen_emits_disconnect failed\n")), -1); } } return 0; } int be_visitor_ccm_pre_proc::visit_consumes (be_consumes *node) { if (!be_global->gen_noeventccm ()) { if (this->gen_get_consumer (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_comsumes - ") ACE_TEXT ("gen_get_consumer failed\n")), -1); } } return 0; } int be_visitor_ccm_pre_proc::visit_home (be_home *node) { AST_Interface *xplicit = this->create_explicit (node); if (xplicit == nullptr) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_home - code generation ") ACE_TEXT ("for explicit interface failed\n")), -1); } AST_Interface *implicit = this->create_implicit (node); if (implicit == nullptr) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_home - code generation ") ACE_TEXT ("for implicit interface failed\n")), -1); } if (this->gen_implicit_ops (node, implicit) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_home - ") ACE_TEXT ("code generation for primary key ") ACE_TEXT ("operations failed\n")), -1); } if (this->create_equivalent (node, xplicit, implicit) == nullptr) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_home - code generation ") ACE_TEXT ("for equivalent interface failed\n")), -1); } return 0; } int be_visitor_ccm_pre_proc::visit_eventtype (be_eventtype *node) { if (!be_global->gen_noeventccm ()) { if (node->ccm_pre_proc_gen ()) { return 0; } if (this->create_event_consumer (node) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("visit_eventtype - code generation ") ACE_TEXT ("for consumer failed\n")), -1); } node->ccm_pre_proc_gen (true); } return 0; } int be_visitor_ccm_pre_proc::visit_eventtype_fwd (be_eventtype_fwd *node) { be_eventtype *fd = dynamic_cast (node->full_definition ()); return this->visit_eventtype (fd); } int be_visitor_ccm_pre_proc::gen_implicit_ops (be_home *node, AST_Interface *implicit) { if (this->gen_create (node, implicit) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("gen_implicit_ops - ") ACE_TEXT ("gen_create failed\n")), -1); } AST_Type *pk = node->primary_key (); if (pk == nullptr) { return 0; } if (!be_global->gen_lwccm ()) { if (this->gen_find_by_primary_key (node, implicit) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("gen_implicit_ops - ") ACE_TEXT ("gen_find_by_primary_key failed\n")), -1); } } if (this->gen_remove (node, implicit) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("gen_implicit_ops - ") ACE_TEXT ("gen_remove failed\n")), -1); } if (!be_global->gen_lwccm ()) { if (this->gen_get_primary_key (node, implicit) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("gen_implicit_ops - ") ACE_TEXT ("gen_get_primary_key failed\n")), -1); } } return 0; } // ************************************************************** int be_visitor_ccm_pre_proc::gen_connect_single (be_uses *node) { // If this facet comes from a porttype, the instantiated // port/mirrorport name is prefixed to the receptacle name. ACE_CString prefix ("connect_"); prefix += this->ctx_->port_prefix (); UTL_ScopedName *op_full_name = this->create_scoped_name (prefix.c_str (), node->local_name ()->get_string (), nullptr, comp_); be_operation *op = nullptr; ACE_NEW_RETURN (op, be_operation (be_global->void_type (), AST_Operation::OP_noflags, nullptr, 0, 0), -1); op->set_defined_in (comp_); op->set_imported (comp_->imported ()); op->set_name (op_full_name); Identifier arg_id ("conxn"); UTL_ScopedName arg_name (&arg_id, nullptr); be_argument *arg = nullptr; ACE_NEW_RETURN (arg, be_argument (AST_Argument::dir_IN, node->uses_type (), &arg_name), -1); arg_id.destroy (); op->be_add_argument (arg); UTL_ExceptList *tail = nullptr; ACE_NEW_RETURN (tail, UTL_ExceptList (this->invalid_connection_, nullptr), -1); UTL_ExceptList *connect_single = nullptr; ACE_NEW_RETURN (connect_single, UTL_ExceptList (this->already_connected_, tail), -1); op->be_add_exceptions (connect_single); if (nullptr == comp_->be_add_operation (op)) { return -1; } return 0; } int be_visitor_ccm_pre_proc::gen_disconnect_single (be_uses *node) { // If this facet comes from a porttype, the instantiated // port/mirrorport name is prefixed to the receptacle name. ACE_CString prefix ("disconnect_"); prefix += this->ctx_->port_prefix (); UTL_ScopedName *op_full_name = this->create_scoped_name (prefix.c_str (), node->local_name ()->get_string (), nullptr, comp_); be_operation *op = nullptr; ACE_NEW_RETURN (op, be_operation (node->uses_type (), AST_Operation::OP_noflags, nullptr, 0, 0), -1); op->set_name (op_full_name); op->set_defined_in (comp_); op->set_imported (comp_->imported ()); UTL_ExceptList *disconnect_single = nullptr; ACE_NEW_RETURN (disconnect_single, UTL_ExceptList (this->no_connection_, nullptr), -1); op->be_add_exceptions (disconnect_single); if (nullptr == comp_->be_add_operation (op)) { return -1; } return 0; } int be_visitor_ccm_pre_proc::gen_get_connection_single (be_uses *node) { // If this facet comes from a porttype, the instantiated // port/mirrorport name is prefixed to the receptacle name. ACE_CString prefix ("get_connection_"); prefix += this->ctx_->port_prefix (); UTL_ScopedName *op_full_name = this->create_scoped_name (prefix.c_str (), node->local_name ()->get_string (), nullptr, comp_); be_operation *op = nullptr; ACE_NEW_RETURN (op, be_operation (node->uses_type (), AST_Operation::OP_noflags, nullptr, 0, 0), -1); op->set_name (op_full_name); op->set_defined_in (comp_); op->set_imported (comp_->imported ()); if (nullptr == comp_->be_add_operation (op)) { return -1; } return 0; } int be_visitor_ccm_pre_proc::gen_connect_multiple (be_uses *node) { // If this facet comes from a porttype, the instantiated // port/mirrorport name is prefixed to the receptacle name. ACE_CString prefix ("connect_"); prefix += this->ctx_->port_prefix (); UTL_ScopedName *op_full_name = this->create_scoped_name (prefix.c_str (), node->local_name ()->get_string (), nullptr, comp_); be_operation *op = nullptr; ACE_NEW_RETURN (op, be_operation (this->cookie_, AST_Operation::OP_noflags, nullptr, 0, 0), -1); op->set_name (op_full_name); op->set_defined_in (comp_); op->set_imported (comp_->imported ()); Identifier arg_id ("connection"); UTL_ScopedName arg_name (&arg_id, nullptr); be_argument *arg = nullptr; ACE_NEW_RETURN (arg, be_argument (AST_Argument::dir_IN, node->uses_type (), &arg_name), -1); arg_id.destroy (); op->be_add_argument (arg); UTL_ExceptList *tail = nullptr; ACE_NEW_RETURN (tail, UTL_ExceptList (this->invalid_connection_, nullptr), -1); UTL_ExceptList *connect_multiple = nullptr; ACE_NEW_RETURN (connect_multiple, UTL_ExceptList (this->exceeded_connection_limit_, tail), -1); op->be_add_exceptions (connect_multiple); if (nullptr == comp_->be_add_operation (op)) { return -1; } return 0; } int be_visitor_ccm_pre_proc::gen_disconnect_multiple (be_uses *node) { // If this facet comes from a porttype, the instantiated // port/mirrorport name is prefixed to the receptacle name. ACE_CString prefix ("disconnect_"); prefix += this->ctx_->port_prefix (); UTL_ScopedName *op_full_name = this->create_scoped_name (prefix.c_str (), node->local_name ()->get_string (), nullptr, comp_); be_operation *op = nullptr; ACE_NEW_RETURN (op, be_operation (node->uses_type (), AST_Operation::OP_noflags, nullptr, 0, 0), -1); op->set_name (op_full_name); op->set_defined_in (comp_); op->set_imported (comp_->imported ()); Identifier arg_id ("ck"); UTL_ScopedName arg_name (&arg_id, nullptr); be_argument *arg = nullptr; ACE_NEW_RETURN (arg, be_argument (AST_Argument::dir_IN, this->cookie_, &arg_name), -1); arg_id.destroy (); op->be_add_argument (arg); UTL_ExceptList *disconnect_multiple = nullptr; ACE_NEW_RETURN (disconnect_multiple, UTL_ExceptList (this->invalid_connection_, nullptr), -1); op->be_add_exceptions (disconnect_multiple); if (nullptr == comp_->be_add_operation (op)) { return -1; } return 0; } int be_visitor_ccm_pre_proc::gen_get_connection_multiple (be_uses *node) { // If this facet comes from a porttype, the instantiated // port/mirrorport name is prefixed to the receptacle name. ACE_CString prefix ("get_connections_"); prefix += this->ctx_->port_prefix (); UTL_ScopedName *op_full_name = this->create_scoped_name (prefix.c_str (), node->local_name ()->get_string (), nullptr, comp_); // Look up the implied IDL typedef created in the front end. // It will be the return type of the created operation. The // sequence was originally created with the port prefix (if // any) in its name, so we must use it here. ACE_CString connections_string (this->ctx_->port_prefix ()); connections_string += node->local_name ()->get_string (); connections_string += "Connections"; Identifier connections_id (connections_string.c_str ()); UTL_ScopedName connections_name (&connections_id, nullptr); AST_Decl *d = comp_->lookup_by_name (&connections_name, true); be_typedef *td = dynamic_cast (d); connections_id.destroy (); be_operation *op = nullptr; ACE_NEW_RETURN (op, be_operation (td, AST_Operation::OP_noflags, nullptr, 0, 0), -1); op->set_name (op_full_name); op->set_defined_in (comp_); op->set_imported (comp_->imported ()); if (nullptr == comp_->be_add_operation (op)) { return -1; } return 0; } int be_visitor_ccm_pre_proc::gen_push_op (be_eventtype *node, AST_Interface *consumer) { if (!be_global->gen_noeventccm ()) { UTL_ScopedName *op_full_name = this->create_scoped_name ("push_", node->local_name (), nullptr, consumer); be_operation *push_op = nullptr; ACE_NEW_RETURN (push_op, be_operation (be_global->void_type (), AST_Operation::OP_noflags, nullptr, false, false), -1); push_op->set_defined_in (consumer); push_op->set_imported (node->imported ()); push_op->set_name (op_full_name); ACE_CString arg_string ("the_", nullptr, false); arg_string += node->local_name (); Identifier arg_id (arg_string.fast_rep ()); UTL_ScopedName arg_name (&arg_id, nullptr); be_argument *arg = nullptr; ACE_NEW_RETURN (arg, be_argument (AST_Argument::dir_IN, node, &arg_name), -1); arg_id.destroy (); push_op->be_add_argument (arg); if (nullptr == consumer->be_add_operation (push_op)) { return -1; } } return 0; } int be_visitor_ccm_pre_proc::gen_subscribe (be_publishes *node) { if ((be_global->gen_lwccm ()) ||(be_global->gen_noeventccm ())) { return 0; } UTL_ScopedName *op_name = this->create_scoped_name ("subscribe_", node->local_name ()->get_string (), nullptr, comp_); be_operation *op = nullptr; ACE_NEW_RETURN (op, be_operation (this->cookie_, AST_Operation::OP_noflags, nullptr, 0, 0), -1); op->set_defined_in (comp_); op->set_imported (comp_->imported ()); op->set_name (op_name); AST_Interface *i = this->lookup_consumer (node); if (i == nullptr) { op->destroy (); delete op; op = nullptr; ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("gen_subscribe - ") ACE_TEXT ("consumer lookup failed\n")), -1); } Identifier arg_id ("consumer"); UTL_ScopedName arg_name (&arg_id, nullptr); be_argument *arg = nullptr; ACE_NEW_RETURN (arg, be_argument (AST_Argument::dir_IN, i, &arg_name), -1); op->be_add_argument (arg); UTL_ExceptList *subscribe = nullptr; ACE_NEW_RETURN (subscribe, UTL_ExceptList (this->exceeded_connection_limit_, nullptr), -1); op->be_add_exceptions (subscribe); if (nullptr == comp_->be_add_operation (op)) { return -1; } return 0; } int be_visitor_ccm_pre_proc::gen_unsubscribe (be_publishes *node) { if (be_global->gen_lwccm () ||be_global->gen_noeventccm ()) { return 0; } AST_Interface *i = this->lookup_consumer (node); if (i == nullptr) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("gen_unsubscribe - ") ACE_TEXT ("consumer lookup failed\n")), -1); } UTL_ScopedName *op_name = this->create_scoped_name ("unsubscribe_", node->local_name ()->get_string (), nullptr, comp_); be_operation *op = nullptr; ACE_NEW_RETURN (op, be_operation (i, AST_Operation::OP_noflags, nullptr, 0, 0), -1); op->set_defined_in (comp_); op->set_imported (comp_->imported ()); op->set_name (op_name); Identifier arg_id ("ck"); UTL_ScopedName arg_name (&arg_id, nullptr); be_argument *arg = nullptr; ACE_NEW_RETURN (arg, be_argument (AST_Argument::dir_IN, this->cookie_, &arg_name), -1); op->be_add_argument (arg); UTL_ExceptList *unsubscribe = nullptr; ACE_NEW_RETURN (unsubscribe, UTL_ExceptList (this->invalid_connection_, nullptr), -1); op->be_add_exceptions (unsubscribe); if (nullptr == comp_->be_add_operation (op)) { return -1; } return 0; } int be_visitor_ccm_pre_proc::gen_emits_connect (be_emits *node) { if ((be_global->gen_lwccm ()) ||(be_global->gen_noeventccm ())) { return 0; } UTL_ScopedName *op_name = this->create_scoped_name ("connect_", node->local_name ()->get_string (), nullptr, comp_); be_operation *op = nullptr; ACE_NEW_RETURN (op, be_operation (be_global->void_type (), AST_Operation::OP_noflags, nullptr, 0, 0), -1); op->set_name (op_name); op->set_defined_in (comp_); op->set_imported (comp_->imported ()); AST_Interface *i = this->lookup_consumer (node); if (i == nullptr) { op->destroy (); delete op; op = nullptr; ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("gen_emits_connect - ") ACE_TEXT ("consumer lookup failed\n")), -1); } Identifier arg_id ("consumer"); UTL_ScopedName arg_name (&arg_id, nullptr); be_argument *arg = nullptr; ACE_NEW_RETURN (arg, be_argument (AST_Argument::dir_IN, i, &arg_name), -1); op->be_add_argument (arg); UTL_ExceptList *emits_connect = nullptr; ACE_NEW_RETURN (emits_connect, UTL_ExceptList (this->already_connected_, nullptr), -1); op->be_add_exceptions (emits_connect); if (nullptr == comp_->be_add_operation (op)) { return -1; } return 0; } int be_visitor_ccm_pre_proc::gen_emits_disconnect (be_emits *node) { if ((be_global->gen_lwccm ()) ||(be_global->gen_noeventccm ())) { return 0; } AST_Interface *i = this->lookup_consumer (node); if (i == nullptr) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("gen_emits_disconnect - ") ACE_TEXT ("consumer lookup failed\n")), -1); } UTL_ScopedName *op_name = this->create_scoped_name ("disconnect_", node->local_name ()->get_string (), nullptr, comp_); be_operation *op = nullptr; ACE_NEW_RETURN (op, be_operation (i, AST_Operation::OP_noflags, nullptr, 0, 0), -1); op->set_name (op_name); op->set_defined_in (comp_); op->set_imported (comp_->imported ()); UTL_ExceptList *emits_disconnect = nullptr; ACE_NEW_RETURN (emits_disconnect, UTL_ExceptList (this->no_connection_, nullptr), -1); op->be_add_exceptions (emits_disconnect); if (nullptr == comp_->be_add_operation (op)) { return -1; } return 0; } int be_visitor_ccm_pre_proc::gen_get_consumer (be_consumes *node) { if (be_global->gen_lwccm () || be_global->gen_noeventccm ()) { return 0; } AST_Interface *i = this->lookup_consumer (node); if (i == nullptr) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("gen_get_consumer - ") ACE_TEXT ("consumer lookup failed\n")), -1); } UTL_ScopedName *op_name = this->create_scoped_name ("get_consumer_", node->local_name ()->get_string (), nullptr, comp_); be_operation *op = nullptr; ACE_NEW_RETURN (op, be_operation (i, AST_Operation::OP_noflags, nullptr, 0, 0), -1); op->set_name (op_name); op->set_defined_in (comp_); op->set_imported (comp_->imported ()); if (nullptr == comp_->be_add_operation (op)) { return -1; } return 0; } int be_visitor_ccm_pre_proc::gen_create (be_home *node, AST_Interface *implicit) { UTL_ScopedName *op_name = this->create_scoped_name (nullptr, "create", nullptr, implicit); be_operation *op = nullptr; ACE_NEW_RETURN (op, be_operation (node->managed_component (), AST_Operation::OP_noflags, nullptr, 0, 0), -1); op->set_name (op_name); AST_Type *pk = node->primary_key (); UTL_ExceptList *exceps = nullptr; ACE_NEW_RETURN (exceps, UTL_ExceptList (this->create_failure_, nullptr), -1); if (pk != nullptr && !be_global->gen_lwccm ()) { Identifier arg_id ("key"); UTL_ScopedName arg_name (&arg_id, nullptr); AST_Argument *arg = nullptr; ACE_NEW_RETURN (arg, be_argument (AST_Argument::dir_IN, pk, &arg_name), -1); arg_id.destroy (); op->be_add_argument (arg); UTL_ExceptList *tail = nullptr; ACE_NEW_RETURN (tail, UTL_ExceptList (this->invalid_key_, nullptr), -1); UTL_ExceptList *middle = nullptr; ACE_NEW_RETURN (middle, UTL_ExceptList (this->duplicate_key_value_, tail), -1); exceps->nconc (middle); } op->be_add_exceptions (exceps); op->set_defined_in (implicit); op->set_imported (node->imported ()); if (nullptr == implicit->be_add_operation (op)) { return -1; } return 0; } int be_visitor_ccm_pre_proc::gen_find_by_primary_key (be_home *node, AST_Interface *implicit) { UTL_ScopedName *op_name = this->create_scoped_name (nullptr, "find_by_primary_key", nullptr, implicit); be_operation *op = nullptr; ACE_NEW_RETURN (op, be_operation (node->managed_component (), AST_Operation::OP_noflags, nullptr, 0, 0), -1); op->set_name (op_name); AST_Type *pk = node->primary_key (); Identifier arg_id ("key"); UTL_ScopedName arg_name (&arg_id, nullptr); AST_Argument *arg = nullptr; ACE_NEW_RETURN (arg, be_argument (AST_Argument::dir_IN, pk, &arg_name), -1); arg_id.destroy (); op->be_add_argument (arg); UTL_ExceptList *tail = nullptr; UTL_ExceptList *middle = nullptr; if (!be_global->gen_lwccm ()) { ACE_NEW_RETURN (tail, UTL_ExceptList (this->invalid_key_, nullptr), -1); ACE_NEW_RETURN (middle, UTL_ExceptList (this->unknown_key_value_, tail), -1); } UTL_ExceptList *exceps = nullptr; ACE_NEW_RETURN (exceps, UTL_ExceptList (this->finder_failure_, middle), -1); op->be_add_exceptions (exceps); op->set_defined_in (implicit); op->set_imported (node->imported ()); if (nullptr == implicit->be_add_operation (op)) { return -1; } return 0; } int be_visitor_ccm_pre_proc::gen_remove (be_home *node, AST_Interface *implicit) { UTL_ScopedName *op_name = this->create_scoped_name (nullptr, "remove", nullptr, implicit); be_operation *op = nullptr; ACE_NEW_RETURN (op, be_operation (be_global->void_type (), AST_Operation::OP_noflags, nullptr, 0, 0), -1); op->set_name (op_name); AST_Type *pk = node->primary_key (); Identifier arg_id ("key"); UTL_ScopedName arg_name (&arg_id, nullptr); AST_Argument *arg = nullptr; ACE_NEW_RETURN (arg, be_argument (AST_Argument::dir_IN, pk, &arg_name), -1); arg_id.destroy (); op->be_add_argument (arg); UTL_ExceptList *tail = nullptr; UTL_ExceptList *middle = nullptr; if (!be_global->gen_lwccm ()) { ACE_NEW_RETURN (tail, UTL_ExceptList (this->invalid_key_, nullptr), -1); ACE_NEW_RETURN (middle, UTL_ExceptList (this->unknown_key_value_, tail), -1); } UTL_ExceptList *exceps = nullptr; ACE_NEW_RETURN (exceps, UTL_ExceptList (this->remove_failure_, middle), -1); op->be_add_exceptions (exceps); op->set_defined_in (implicit); op->set_imported (node->imported ()); if (nullptr == implicit->be_add_operation (op)) { return -1; } return 0; } int be_visitor_ccm_pre_proc::gen_get_primary_key (be_home *node, AST_Interface *implicit) { UTL_ScopedName *op_name = this->create_scoped_name (nullptr, "get_primary_key", nullptr, implicit); be_operation *op = nullptr; ACE_NEW_RETURN (op, be_operation (node->primary_key (), AST_Operation::OP_noflags, nullptr, 0, 0), -1); op->set_name (op_name); Identifier arg_id ("comp"); UTL_ScopedName arg_name (&arg_id, nullptr); AST_Argument *arg = nullptr; ACE_NEW_RETURN (arg, be_argument (AST_Argument::dir_IN, node->managed_component (), &arg_name), -1); arg_id.destroy (); op->be_add_argument (arg); op->set_defined_in (implicit); op->set_imported (node->imported ()); if (nullptr == implicit->be_add_operation (op)) { return -1; } return 0; } int be_visitor_ccm_pre_proc::gen_extended_port (be_porttype *pt) { if (this->visit_scope (pt) == -1) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("gen_extended_port - ") ACE_TEXT ("visit_scope for porttype failed\n")), -1); } return 0; } int be_visitor_ccm_pre_proc::lookup_cookie () { if (this->cookie_ == nullptr) { Identifier local_id ("Cookie"); UTL_ScopedName local_name (&local_id, nullptr); UTL_ScopedName cookie_name (&this->module_id_, &local_name); AST_Decl *d = idl_global->root ()->lookup_by_name (&cookie_name, true); local_id.destroy (); if (d == nullptr) { idl_global->err ()->lookup_error (&cookie_name); return -1; } this->cookie_ = dynamic_cast (d); if (this->cookie_ == nullptr) { idl_global->err ()->valuetype_expected (d); return -1; } } return 0; } int be_visitor_ccm_pre_proc::lookup_exceptions () { int status = 0; for (int i = 0; i < N_LW_EXCEPS; ++i) { status = this->lookup_one_exception (LW_EXCEP_NAMES[i], LW_EXCEPS[i]); if (status == -1) { return -1; } } this->already_connected_ = LW_EXCEPS[0]; this->invalid_connection_ = LW_EXCEPS[1]; this->no_connection_ = LW_EXCEPS[2]; this->exceeded_connection_limit_ = LW_EXCEPS[3]; this->create_failure_ = LW_EXCEPS[4]; this->remove_failure_ = LW_EXCEPS[5]; this->finder_failure_ = LW_EXCEPS[6]; if (!be_global->gen_lwccm ()) { for (int j = 0; j < N_ADDL_EXCEPS; ++j) { status = this->lookup_one_exception (ADDL_EXCEP_NAMES[j], ADDL_EXCEPS[j]); if (status == -1) { return -1; } } this->invalid_key_ = ADDL_EXCEPS[0]; this->unknown_key_value_ = ADDL_EXCEPS[1]; this->duplicate_key_value_ = ADDL_EXCEPS[2]; } return 0; } int be_visitor_ccm_pre_proc::lookup_one_exception (const char *name, be_exception *&result) { Identifier id (name); UTL_ScopedName local_name (&id, nullptr); UTL_ScopedName scoped_name (&this->module_id_, &local_name); AST_Decl *d = idl_global->root ()->lookup_by_name (&scoped_name, true); id.destroy (); if (d == nullptr) { idl_global->err ()->lookup_error (&scoped_name); return -1; } result = dynamic_cast (d); if (result == nullptr) { return -1; } return 0; } int be_visitor_ccm_pre_proc::create_event_consumer (be_eventtype *node) { UTL_Scope *s = node->defined_in (); UTL_ScopedName *consumer_name = this->create_scoped_name (nullptr, node->local_name (), "Consumer", ScopeAsDecl (node->defined_in ())); /// We need to create event consumers even for forward /// declared eventtypes. Since forward declarations can /// appear any number of times, we need to check that this /// event consumer hasn't already been created. if (s->lookup_by_name (consumer_name, true) != nullptr) { return 0; } AST_Interface *event_consumer = nullptr; AST_Module *m = dynamic_cast (s); // We're at global scope here so we need to fool the scope stack // for a minute so the correct repo id can be calculated at // interface construction time. idl_global->scopes ().push (s); Identifier parent_id ("EventConsumerBase"); UTL_ScopedName parent_local_name (&parent_id, nullptr); UTL_ScopedName parent_full_name (&this->module_id_, &parent_local_name); UTL_NameList parent_list (&parent_full_name, nullptr); FE_InterfaceHeader header (consumer_name, &parent_list, false, false, true); ACE_NEW_RETURN (event_consumer, be_interface (header.name (), header.inherits (), header.n_inherits (), header.inherits_flat (), header.n_inherits_flat (), false, false), -1); parent_id.destroy (); // Back to reality. idl_global->scopes ().pop (); event_consumer->set_defined_in (s); event_consumer->set_imported (node->imported ()); event_consumer->set_name (consumer_name); be_interface *bec = dynamic_cast (event_consumer); bec->original_interface (node); // Set repo id to 0, so it will be recomputed on the next access, // and set the prefix to the eventtype's prefix. All this is // necessary in case the eventtype's prefix was modified after // its declaration. We assume 'implied IDL' means that the // derived event consumer interface should have the same prefix. event_consumer->repoID (nullptr); event_consumer->prefix (const_cast (node->prefix ())); dynamic_cast (event_consumer)->gen_fwd_helper_name (); m->be_add_interface (event_consumer); return this->gen_push_op (node, event_consumer); } AST_Interface * be_visitor_ccm_pre_proc::lookup_consumer (be_field *node) { AST_Type *impl = node->field_type (); ACE_CString rettype_string (impl->local_name ()->get_string ()); rettype_string += "Consumer"; Identifier rettype_id (rettype_string.fast_rep ()); AST_Decl *d = impl->defined_in ()->lookup_by_name_local (&rettype_id, false); rettype_id.destroy (); if (d == nullptr) { return nullptr; } AST_Interface *i = dynamic_cast (d); if (i == nullptr) { idl_global->err ()->interface_expected (d); return nullptr; } return i; } AST_Interface * be_visitor_ccm_pre_proc::create_explicit (be_home *node) { be_visitor_xplicit_pre_proc v (this->ctx_); if (v.visit_home (node) != 0) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc::") ACE_TEXT ("create_explicit - ") ACE_TEXT ("home xplicit visitor failed\n")), 0); } return v.xplicit (); } AST_Interface * be_visitor_ccm_pre_proc::create_implicit (be_home *node) { Identifier *parent_id = nullptr; ACE_NEW_RETURN (parent_id, Identifier ("KeylessCCMHome"), nullptr); UTL_ScopedName *parent_local_name = nullptr; ACE_NEW_RETURN (parent_local_name, UTL_ScopedName (parent_id, nullptr), nullptr); UTL_ScopedName *parent_full_name = nullptr; ACE_NEW_RETURN (parent_full_name, UTL_ScopedName (this->module_id_.copy (), parent_local_name), nullptr); UTL_NameList parent_list (parent_full_name, nullptr); UTL_NameList *parent_list_ptr = nullptr; if (node->primary_key () == nullptr) { parent_list_ptr = &parent_list; } FE_InterfaceHeader header (nullptr, parent_list_ptr, false, false, true); // We're at global scope here so we need to fool the scope stack // for a minute so the correct repo id can be calculated at // interface construction time. idl_global->scopes ().push (node->defined_in ()); UTL_ScopedName *implicit_name = this->create_scoped_name (nullptr, node->local_name (), "Implicit", ScopeAsDecl (node->defined_in ())); be_interface *i = nullptr; ACE_NEW_RETURN (i, be_interface (implicit_name, header.inherits (), header.n_inherits (), header.inherits_flat (), header.n_inherits_flat (), false, false), nullptr); // Back to reality. idl_global->scopes ().pop (); header.destroy (); parent_list.destroy (); // So we can generate the proper typecode. i->home_equiv (true); i->set_name (implicit_name); i->set_defined_in (node->defined_in ()); i->set_imported (node->imported ()); i->gen_fwd_helper_name (); i->original_interface (node); AST_Module *m = dynamic_cast (node->defined_in ()); m->be_add_interface (i); return i; } AST_Interface * be_visitor_ccm_pre_proc::create_equivalent (be_home *node, AST_Interface *xplicit, AST_Interface *implicit) { UTL_Scope *s = node->defined_in (); UTL_ScopedName *equiv_name = this->create_scoped_name (nullptr, node->local_name (), nullptr, ScopeAsDecl (s)); UTL_NameList tail (implicit->name (), nullptr); UTL_NameList parent_list (xplicit->name (), &tail); FE_InterfaceHeader header (nullptr, &parent_list, false, false, true); // We're at global scope here so we need to fool the scope stack // for a minute so the correct repo id can be calculated at // interface construction time. idl_global->scopes ().push (node->defined_in ()); be_interface *retval = nullptr; ACE_NEW_RETURN (retval, be_interface (equiv_name, header.inherits (), header.n_inherits (), header.inherits_flat (), header.n_inherits_flat (), false, false), nullptr); // Back to reality. idl_global->scopes ().pop (); // So we can generate the proper typecode. retval->home_equiv (true); retval->set_name (equiv_name); retval->set_defined_in (s); retval->set_imported (node->imported ()); retval->gen_fwd_helper_name (); retval->original_interface (node); UTL_ScopedName *unmangled_name = static_cast (node->name ()->copy ()); UTL_ScopedName *mangled_name = this->create_scoped_name (nullptr, node->local_name (), "_tao_home_name_extension", ScopeAsDecl (s)); node->set_name (mangled_name); AST_Module *m = dynamic_cast (s); /// Calling be_add_interface() here calls add_to_referenced(), /// which will give a redef error. m->add_to_scope (retval); node->set_name (unmangled_name); return retval; } UTL_ScopedName * be_visitor_ccm_pre_proc::create_scoped_name (const char *prefix, const char *local_name, const char *suffix, AST_Decl *parent) { ACE_CString local_string (prefix, nullptr, false); local_string += local_name; local_string += suffix; Identifier *local_id = nullptr; ACE_NEW_RETURN (local_id, Identifier (local_string.fast_rep ()), nullptr); UTL_ScopedName *last_segment = nullptr; ACE_NEW_RETURN (last_segment, UTL_ScopedName (local_id, nullptr), nullptr); UTL_ScopedName *full_name = static_cast (parent->name ()->copy ()); full_name->nconc (last_segment); return full_name; } UTL_NameList * be_visitor_ccm_pre_proc::compute_inheritance (be_home *node) { UTL_NameList *retval = nullptr; if (node->base_home () == nullptr) { Identifier *local_id = nullptr; ACE_NEW_RETURN (local_id, Identifier ("CCMHome"), nullptr); UTL_ScopedName *local_name = nullptr; ACE_NEW_RETURN (local_name, UTL_ScopedName (local_id, nullptr), nullptr); UTL_ScopedName *full_name = nullptr; ACE_NEW_RETURN (full_name, UTL_ScopedName (this->module_id_.copy (), local_name), nullptr); ACE_NEW_RETURN (retval, UTL_NameList (full_name, nullptr), nullptr); } else { ACE_CString new_local ( node->base_home ()->local_name ()->get_string () ); new_local += "Explicit"; UTL_ScopedName *parent_name = static_cast (node->base_home ()->name ()->copy ()); parent_name->last_component ()->replace_string (new_local.c_str ()); ACE_NEW_RETURN (retval, UTL_NameList (parent_name, nullptr), nullptr); } long n_supports = node->n_inherits (); UTL_ScopedName *supported_name = nullptr; UTL_NameList *conc_value = nullptr; for (long i = 0; i < n_supports; ++i) { supported_name = static_cast (node->inherits ()[i]->name ()->copy ()); ACE_NEW_RETURN (conc_value, UTL_NameList (supported_name, nullptr), nullptr); retval->nconc (conc_value); } return retval; } int be_visitor_ccm_pre_proc::generate_ami4ccm_uses () { /// The interfaces in the list below are from this IDL file, /// which then must be processed with the -GC option, so we /// know we'll get here - a good place to generate the *A.idl /// file containing the local interfaces and connector /// associated with each interface in the list. ACE_Unbounded_Queue &ccm_ami_receps = idl_global->ciao_ami_recep_names (); /// If the queue is empty, we're done. if (ccm_ami_receps.size () == 0) { return 0; } for (ACE_Unbounded_Queue::CONST_ITERATOR i ( ccm_ami_receps); ! i.done (); i.advance ()) { char **item = nullptr; i.next (item); UTL_ScopedName *sn = FE_Utils::string_to_scoped_name (*item); UTL_Scope *s = idl_global->scopes ().top_non_null (); AST_Decl *d = s->lookup_by_name (sn, true); if (d == nullptr) { idl_global->err ()->lookup_error (sn); sn->destroy (); delete sn; sn = nullptr; continue; } sn->destroy (); delete sn; sn = nullptr; be_uses *u = dynamic_cast (d); if (u == nullptr) { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("be_visitor_ccm_pre_proc") ACE_TEXT ("::generate_ami4ccm_uses - ") ACE_TEXT ("narrow to receptacle ") ACE_TEXT ("failed\n")), -1); } be_interface *iface = dynamic_cast (u->uses_type ()); /// The real AMI_xxx exists only in the *A.idl file, so /// we create a dummy as the uses type for the implied /// receptacle created below, but only if it hasn't /// already been created for this uses type. be_interface *ami_iface = dynamic_cast (iface->ami4ccm_uses ()); if (ami_iface == nullptr) { ACE_CString iname ("AMI4CCM_"); iname += iface->local_name (); Identifier itmp_id (iname.c_str ()); UTL_ScopedName itmp_sn (&itmp_id, nullptr); s = iface->defined_in (); idl_global->scopes ().push (s); ACE_NEW_RETURN (ami_iface, be_interface (&itmp_sn, nullptr, 0, nullptr, 0, true, false), -1); idl_global->scopes ().pop (); /// Make it imported so it doesn't trigger /// any unwanted code generation. ami_iface->set_imported (true); s->add_to_scope (ami_iface); iface->ami4ccm_uses (ami_iface); } /// Now create the receptacle, passing in /// the local interface created above as the /// uses type. We don't generate anything /// in the main IDL file from the interface's /// contents, so it's ok that it's empty. ACE_CString uname ("sendc_"); uname += u->local_name ()->get_string (); Identifier utmp_id (uname.c_str ()); UTL_ScopedName utmp_sn (&utmp_id, nullptr); s = u->defined_in (); idl_global->scopes ().push (s); be_uses *ami_uses = nullptr; ACE_NEW_RETURN (ami_uses, be_uses (&utmp_sn, ami_iface, u->is_multiple ()), -1); s->add_to_scope (ami_uses); idl_global->scopes ().pop (); if (u->is_multiple ()) { /* AST_Type *t = u->uses_type (); ACE_CString fname (t->file_name ()); char *dummy = 0; char *path = ACE_OS::realpath (fname.c_str (), dummy); ACE_DEBUG ((LM_DEBUG, "utype file: %s\n", path)); */ // Grammar ensures this narrowing will never be 0. AST_Component *c = dynamic_cast (s); FE_Utils::create_uses_multiple_stuff (c, ami_uses); } } return 0; }