diff options
Diffstat (limited to 'ACE/TAO/TAO_IDL/be/be_visitor_operation/upcall_command_ss.cpp')
-rw-r--r-- | ACE/TAO/TAO_IDL/be/be_visitor_operation/upcall_command_ss.cpp | 455 |
1 files changed, 455 insertions, 0 deletions
diff --git a/ACE/TAO/TAO_IDL/be/be_visitor_operation/upcall_command_ss.cpp b/ACE/TAO/TAO_IDL/be/be_visitor_operation/upcall_command_ss.cpp new file mode 100644 index 00000000000..857f14ec7f9 --- /dev/null +++ b/ACE/TAO/TAO_IDL/be/be_visitor_operation/upcall_command_ss.cpp @@ -0,0 +1,455 @@ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO IDL +// +// = FILENAME +// upcall_command_ss.cpp +// +// = DESCRIPTION +// Visitor that generates operation-specific TAO::Upcall_Command +// objects in skeletons. +// +// = AUTHOR +// Ossama Othman +// +// ============================================================================ + + +ACE_RCSID (be_visitor_operation, + upcall_command_ss, + "$Id$") + +be_visitor_operation_upcall_command_ss +::be_visitor_operation_upcall_command_ss ( + be_visitor_context *ctx) + : be_visitor_operation (ctx) +{ +} + +be_visitor_operation_upcall_command_ss +::~be_visitor_operation_upcall_command_ss (void) +{ +} + +// The following needs to be done to deal until the MSVC compiler's broken +// handling of namespaces is fixed (hopefully forthcoming in version 7). +int +be_visitor_operation_upcall_command_ss +::gen_nested_namespace_begin (be_module *node) +{ + TAO_OutStream *os = this->ctx_->stream (); + char *item_name = 0; + bool first_level = true; + + for (UTL_IdListActiveIterator i (node->name ()); !i.is_done (); i.next ()) + { + item_name = i.item ()->get_string (); + + if (ACE_OS::strcmp (item_name, "") != 0) + { + // Leave the outermost root scope. + *os << "namespace "; + + if (first_level) + { + // We are outermost module. + *os << "POA_"; + first_level = false; + } + + *os << item_name << be_nl + << "{" << be_idt_nl; + } + } + + return 0; +} + +// The following needs to be done to deal until the MSVC compiler's broken +// handling of namespaces is fixed (hopefully forthcoming in version 7). +int +be_visitor_operation_upcall_command_ss +::gen_nested_namespace_end (be_module *node) +{ + TAO_OutStream *os = this->ctx_->stream (); + + for (UTL_IdListActiveIterator i (node->name ()); !i.is_done (); i.next ()) + { + if (ACE_OS::strcmp (i.item ()->get_string (), "") != 0) + { + // Leave the outermost root scope. + *os << be_uidt_nl << "}" << be_nl; + } + } + + return 0; +} + +int +be_visitor_operation_upcall_command_ss::visit (be_operation * node, + char const * full_skel_name, + char const * upcall_command_name) +{ + be_interface * const intf = this->ctx_->attribute () + ? be_interface::narrow_from_scope (this->ctx_->attribute ()->defined_in ()) + : be_interface::narrow_from_scope (node->defined_in ()); + + if (!intf) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_upcall_command_ss::" + "visit - " + "bad interface scope\n"), + -1); + } + + be_module *module = 0; + + // Is our enclosing scope a module? We need this check because for + // platforms that support namespaces, the typecode must be declared + // extern. + if (intf->is_nested () && + intf->defined_in ()->scope_node_type () == AST_Decl::NT_module) + { + module = be_module::narrow_from_scope (intf->defined_in ()); + + if (!module || (this->gen_nested_namespace_begin (module) == -1)) + { + ACE_ERROR_RETURN ((LM_ERROR, + "be_visitor_operation_upcall_command_ss::visit - " + "Error parsing nested name\n"), + -1); + } + } + + be_visitor_context ctx (*this->ctx_); + + // save the node. + this->ctx_->node (node); + + TAO_OutStream & os = *this->ctx_->stream (); + + os << be_nl << be_nl << "// TAO_IDL - Generated from" << be_nl + << "// " << __FILE__ << ":" << __LINE__ << be_nl << be_nl; + + // Generate the operation-specific TAO::Upcall_Command concrete + // class. + + // Generate an operation-specific concrete TAO::Upcall_Command + // class, an instance of which will be invoked by the + // TAO::Upcall_Wrapper object. + + os << "class " << upcall_command_name << be_nl + << " : public TAO::Upcall_Command" << be_nl + << "{" << be_nl + << "public:" << be_idt_nl ; + + // Generate constructor + os << "inline " << upcall_command_name + << " (" << be_idt_nl + << full_skel_name << " * servant"; + + // No need to accept an argument array parameter if the operation + // has no arguments. + if (!node->void_return_type () || node->argument_count () > 0) + { + os << "," << be_nl; + + if (be_global->gen_thru_poa_collocation ()) + os << "TAO_Operation_Details const * operation_details," << be_nl; + + os << "TAO::Argument * const args[])" << be_nl; + } + else + { + os << ")" << be_nl; + } + + os << ": servant_ (servant)"; + + // If the operation has no arguments don't generate a member + // initializer for the class argument array member/attribute. + if (!node->void_return_type () || node->argument_count () > 0) + { + os << be_idt_nl; + + if (be_global->gen_thru_poa_collocation ()) + { + os << ", operation_details_ (operation_details)" << be_nl; + } + + os << ", args_ (args)" << be_uidt; + } + + os << be_uidt_nl; + + os << "{" << be_nl + << "}" << be_nl << be_nl; + + // Generate execute() method. + os << "virtual void execute (void)" << be_nl + << "{" << be_idt_nl; + + if (!node->void_return_type ()) + { + os << "TAO::SArg_Traits< "; + + + this->gen_arg_template_param_name (node, + node->return_type (), + &os); + + os << ">::ret_arg_type retval =" << be_idt_nl; + + if (be_global->gen_thru_poa_collocation ()) + { + os << "TAO::Portable_Server::get_ret_arg< "; + + this->gen_arg_template_param_name (node, + node->return_type (), + &os); + + os << "> (" << be_idt_nl + << "this->operation_details_," << be_nl + << "this->args_);" << be_uidt; + } + else + { + os << "static_cast<TAO::SArg_Traits< "; + + this->gen_arg_template_param_name (node, + node->return_type (), + &os); + + os << ">::ret_val *> (this->args_[0])->arg ();"; + } + + os << be_uidt_nl << be_nl; + } + + if (this->gen_upcall (node) == -1) + { + return -1; + } + + os << "}" << be_uidt_nl << be_nl; + + // Generate class attributes. + os << "private:" << be_idt_nl + << full_skel_name << " * const servant_;"; + + // Don't bother generating an argument array attribute if the + // operation has no arguments. + if (!node->void_return_type () || node->argument_count () > 0) + { + os << be_nl; + + if (be_global->gen_thru_poa_collocation ()) + os << "TAO_Operation_Details const * const operation_details_;" << be_nl; + + os << "TAO::Argument * const * const args_;"; + } + + os << be_uidt_nl + << "};"; + + if (module != 0) + { + if (this->gen_nested_namespace_end (module) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "be_visitor_operation_upcall_command_ss::visit - " + "Error parsing nested name\n"), + -1); + } + } + + return 0; +} + +int +be_visitor_operation_upcall_command_ss::gen_upcall (be_operation * node) +{ + TAO_OutStream & os = *this->ctx_->stream (); + + UTL_ScopeActiveIterator si (node, + UTL_Scope::IK_decls); + + unsigned int index = 1; + const char *op_name = node->flat_name (); + static const char *excep_suffix = "_excep"; + static const size_t excep_suffix_len = ACE_OS::strlen (excep_suffix); + bool excep_method = ((ACE_OS::strstr (op_name, excep_suffix) + + excep_suffix_len) == + (op_name + ACE_OS::strlen (op_name))); + for (; !si.is_done (); si.next (), ++index) + { + AST_Argument * const arg = + AST_Argument::narrow_from_decl (si.item ()); + + // Finish the check for the _excep method + if (excep_method) + { + excep_method = false; + be_argument *argument = + be_argument::narrow_from_decl (si.item ()); + be_valuetype *value_type = + be_valuetype::narrow_from_decl (argument->field_type ()); + + if (value_type != 0) + { + static const char *excepholder = "ExceptionHolder"; + static const size_t excepholder_len = + ACE_OS::strlen (excepholder); + const char *param_name = value_type->full_name (); + excep_method = + ((ACE_OS::strstr (param_name, excepholder) + + excepholder_len) == + (param_name + ACE_OS::strlen (param_name))); + } + } + + os << "TAO::SArg_Traits< "; + + this->gen_arg_template_param_name (arg, + arg->field_type (), + &os); + + os << ">::"; + + switch (arg->direction ()) + { + case AST_Argument::dir_IN: + os << "in"; + break; + case AST_Argument::dir_INOUT: + os << "inout"; + break; + case AST_Argument::dir_OUT: + os << "out"; + default: + break; + } + + os << "_arg_type arg_" << index << " =" << be_idt_nl; + + if (be_global->gen_thru_poa_collocation ()) + { + os << "TAO::Portable_Server::get_"; + + switch (arg->direction ()) + { + case AST_Argument::dir_IN: + os << "in"; + break; + case AST_Argument::dir_INOUT: + os << "inout"; + break; + case AST_Argument::dir_OUT: + os << "out"; + default: + break; + } + + os << "_arg< "; + + this->gen_arg_template_param_name (arg, + arg->field_type (), + &os); + + os << "> (" << be_idt_nl + << "this->operation_details_," << be_nl + << "this->args_," << be_nl + << index << ");" << be_uidt_nl; + } + else + { + os << "static_cast<TAO::SArg_Traits< "; + + this->gen_arg_template_param_name (arg, + arg->field_type (), + &os); + + os << ">::"; + + switch (arg->direction ()) + { + case AST_Argument::dir_IN: + os << "in"; + break; + case AST_Argument::dir_INOUT: + os << "inout"; + break; + case AST_Argument::dir_OUT: + os << "out"; + default: + break; + } + + os << "_arg_val *> (this->args_[" << index << "])->arg ();" + << be_nl; + } + + os << be_uidt_nl; + + } + + --index; + + // We have determined that this is an "_excep" method, there is exactly + // one argument. Now, if the node has exceptions, we're in business. + if (excep_method && index == 1 && node->exceptions()) + { + be_visitor_operation_exceptlist_cs exceplist (this->ctx ()); + exceplist.visit_operation (node); + + unsigned int exceptions_count = 0; + for (UTL_ExceptlistActiveIterator ei (node->exceptions ()); + !ei.is_done (); ei.next ()) + { + ++exceptions_count; + } + + os << be_nl + << "TAO::ExceptionHolder *tao_excepholder = " << be_idt_nl + << "dynamic_cast<TAO::ExceptionHolder *> (arg_" << index + << ");" << be_uidt_nl + << "if (tao_excepholder != 0)" << be_idt_nl + << "{" << be_idt_nl + << "tao_excepholder->set_exception_data " + "(_tao_" << op_name << "_exceptiondata, " << exceptions_count << ");" << be_uidt_nl + << "}" << be_uidt_nl + << be_nl; + } + + if (!node->void_return_type ()) + { + os << "retval =" << be_idt_nl; + } + + os << "this->servant_->" << node->local_name () << " (" + << be_idt; + + size_t const count = node->argument_count (); + + for (unsigned int i = 0; i < count; ++i) + { + os << be_nl + << (i == 0 ? "" : ", ") << "arg_" << i + 1; + } + + os << ");"; + + if (!node->void_return_type ()) + { + os << be_uidt; + } + + os << be_uidt + << be_uidt_nl; + + return 0; +} |