diff options
Diffstat (limited to 'ACE/TAO/TAO_IDL/be/be_visitor_arg_traits.cpp')
-rw-r--r-- | ACE/TAO/TAO_IDL/be/be_visitor_arg_traits.cpp | 1178 |
1 files changed, 1178 insertions, 0 deletions
diff --git a/ACE/TAO/TAO_IDL/be/be_visitor_arg_traits.cpp b/ACE/TAO/TAO_IDL/be/be_visitor_arg_traits.cpp new file mode 100644 index 00000000000..ad42243dd6e --- /dev/null +++ b/ACE/TAO/TAO_IDL/be/be_visitor_arg_traits.cpp @@ -0,0 +1,1178 @@ +//============================================================================= +/** +* @file be_visitor_arg_traits.cpp +* +* $Id$ +* +* This visitor generates template specializations for argument traits classes. +* +* @author Jeff Parsons <j.parsons@vanderbilt.edu> +*/ +//============================================================================= + +#include "be_visitor_arg_traits.h" +#include "be_visitor_context.h" +#include "be_root.h" +#include "be_module.h" +#include "be_interface.h" +#include "be_valuebox.h" +#include "be_valuetype.h" +#include "be_interface_fwd.h" +#include "be_valuetype_fwd.h" +#include "be_component_fwd.h" +#include "be_component.h" +#include "be_home.h" +#include "be_eventtype.h" +#include "be_eventtype_fwd.h" +#include "be_operation.h" +#include "be_attribute.h" +#include "be_argument.h" +#include "be_array.h" +#include "be_enum.h" +#include "be_predefined_type.h" +#include "be_sequence.h" +#include "be_string.h" +#include "be_structure.h" +#include "be_field.h" +#include "be_union.h" +#include "be_union_branch.h" +#include "be_typedef.h" +#include "be_helper.h" +#include "be_extern.h" +#include "utl_identifier.h" +#include "idl_defines.h" +#include "nr_extern.h" +#include "ace/Log_Msg.h" + +#include <string> + + +ACE_RCSID (be, + be_visitor_arg_traits, + "$Id$") + +be_visitor_arg_traits::be_visitor_arg_traits (const char *S, + be_visitor_context *ctx) + : be_visitor_scope (ctx), + S_ (ACE::strnew (S)) +{ +} + +be_visitor_arg_traits::~be_visitor_arg_traits (void) +{ + delete [] this->S_; +} + +int +be_visitor_arg_traits::visit_root (be_root *node) +{ + TAO_OutStream *os = this->ctx_->stream (); + + *os << be_nl << be_nl + << "// TAO_IDL - Generated from" << be_nl + << "// " << __FILE__ << ":" << __LINE__; + + *os << be_nl + << be_global->core_versioning_begin (); + + *os << be_nl << be_nl + << "// Arg traits specializations." << be_nl + << "namespace TAO" << be_nl + << "{" << be_idt; + + if (be_global->ami_call_back ()) + { + int const status = + this->visit_valuetype (be_global->messaging_exceptionholder ()); + + if (-1 == status) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_arg_traits::" + "visit_root - visit " + "Messaging::ExceptionHolder failed\n"), + -1); + } + } + + if (this->visit_scope (node) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_arg_traits::" + "visit_root - visit scope failed\n"), + -1); + } + + *os << be_uidt_nl + << "}" << be_nl; + + *os << be_global->core_versioning_end () << be_nl; + + return 0; +} + +int +be_visitor_arg_traits::visit_module (be_module *node) +{ + if (this->visit_scope (node) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_arg_traits::" + "visit_module - visit scope failed\n"), + -1); + } + + return 0; +} + +int +be_visitor_arg_traits::visit_interface (be_interface *node) +{ + if (this->generated (node)) + { + return 0; + } + + if (node->seen_in_operation ()) + { + TAO_OutStream *os = this->ctx_->stream (); + + *os << be_nl << be_nl << "// TAO_IDL - Generated from" << be_nl + << "// " << __FILE__ << ":" << __LINE__; + + std::string guard_suffix = + std::string (this->S_) + std::string ("arg_traits"); + + // This should be generated even for imported nodes. The ifdef + // guard prevents multiple declarations. + os->gen_ifdef_macro (node->flat_name (), guard_suffix.c_str (), false); + + *os << be_nl << be_nl + << "template<>" << be_nl + << "class " + << " " << this->S_ << "Arg_Traits<" + << node->name () << ">" << be_idt_nl + << ": public" << be_idt << be_idt_nl + << "Object_" << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl + << node->name () << "_ptr," << be_nl + << node->name () << "_var," << be_nl + << node->name () << "_out"; + + if (ACE_OS::strlen (this->S_) == 0) + { + *os << "," << be_nl + << "TAO::Objref_Traits<" << node->name () << ">"; + } + + *os << "," << be_nl << this->insert_policy() << " <" + << node->name () << "_ptr>" << be_uidt_nl + << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl + << "{" << be_nl + << "};"; + + os->gen_endif (); + } + + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_arg_traits::" + "visit_interface - visit scope failed\n"), + -1); + } + + this->generated (node, true); + return 0; +} + +int +be_visitor_arg_traits::visit_interface_fwd (be_interface_fwd *node) +{ + // If a full definition with the same name in the same scope + // has been seen, then it will have gone through visit_interface() + // already. + if (this->generated (node)) + { + return 0; + } + + be_interface *fd = + be_interface::narrow_from_decl (node->full_definition ()); + + // The logic in visit_interface() should handle what gets generated + // and what doesn't. + if (this->visit_interface (fd) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_arg_traits::" + "visit_interface_fwd - code generation failed\n"), + -1); + } + + this->generated (node, true); + return 0; +} + +int +be_visitor_arg_traits::visit_valuebox (be_valuebox *node) +{ + if (this->generated (node)) + { + return 0; + } + + if (node->seen_in_operation ()) + { + TAO_OutStream & os = *this->ctx_->stream (); + + os << be_nl << be_nl + << "// TAO_IDL - Generated from" << be_nl + << "// " << __FILE__ << ":" << __LINE__; + + std::string guard_suffix = + std::string (this->S_) + std::string ("arg_traits"); + + // This should be generated even for imported nodes. The ifdef + // guard prevents multiple declarations. + os.gen_ifdef_macro (node->flat_name (), guard_suffix.c_str (), false); + + os << be_nl << be_nl + << "template<>" << be_nl + << "class " + << this->S_ << "Arg_Traits<" + << node->name () << ">" << be_idt_nl + << ": public" << be_idt << be_idt_nl + << "Object_" << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl + << node->name () << " *," << be_nl + << node->name () << "_var," << be_nl + << node->name () << "_out"; + + // The SArgument classes don't need the traits parameter (yet?) + if (ACE_OS::strlen (this->S_) == 0) + { + os << "," << be_nl + << "TAO::Value_Traits<" << node->name () << ">"; + } + + os << "," << be_nl << this->insert_policy() << " <" + << node->name () << "*>" << be_uidt_nl + << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl + << "{" << be_nl + << "};"; + + os.gen_endif (); + } + + this->generated (node, true); + return 0; +} + +int +be_visitor_arg_traits::visit_valuetype (be_valuetype *node) +{ + if (this->generated (node)) + { + return 0; + } + + if (node->seen_in_operation ()) + { + TAO_OutStream & os = *this->ctx_->stream (); + + os << be_nl << be_nl + << "// TAO_IDL - Generated from" << be_nl + << "// " << __FILE__ << ":" << __LINE__; + + std::string guard_suffix = + std::string (this->S_) + std::string ("arg_traits"); + + // This should be generated even for imported nodes. The ifdef + // guard prevents multiple declarations. + os.gen_ifdef_macro (node->flat_name (), guard_suffix.c_str (), false); + + os << be_nl << be_nl + << "template<>" << be_nl + << "class " + << this->S_ << "Arg_Traits<" + << node->name () << ">" << be_idt_nl + << ": public" << be_idt << be_idt_nl + << "Object_" << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl + << node->name () << " *," << be_nl + << node->name () << "_var," << be_nl + << node->name () << "_out"; + + // The SArgument classes don't need the traits parameter (yet?) + if (ACE_OS::strlen (this->S_) == 0) + { + os << "," << be_nl + << "TAO::Value_Traits<" << node->name () << ">"; + } + + os << "," << be_nl << this->insert_policy() << " <" + << node->name () << "*>" << be_uidt_nl + << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl + << "{" << be_nl + << "};"; + + os.gen_endif (); + } + + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_arg_traits::" + "visit_valuetype - visit scope failed\n"), + -1); + } + + this->generated (node, true); + return 0; +} + +int +be_visitor_arg_traits::visit_valuetype_fwd (be_valuetype_fwd *node) +{ + if (this->generated (node)) + { + return 0; + } + + be_valuetype *fd = + be_valuetype::narrow_from_decl (node->full_definition ()); + + // The logic in visit_valuetype() should handle what gets generated + // and what doesn't. + int status = this->visit_valuetype (fd); + + if (status != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_arg_traits::" + "visit_valuetype_fwd - code generation failed\n"), + -1); + } + + this->generated (node, true); + return 0; +} + +int +be_visitor_arg_traits::visit_eventtype (be_eventtype *node) +{ + return this->visit_valuetype (node); +} + +int +be_visitor_arg_traits::visit_eventtype_fwd (be_eventtype_fwd *node) +{ + return this->visit_valuetype_fwd (node); +} + +int +be_visitor_arg_traits::visit_operation (be_operation *node) +{ + if (this->generated (node) || node->is_local () || node->imported ()) + { + return 0; + } + + AST_Type *rt = node->return_type (); + AST_Decl::NodeType nt = rt->node_type (); + + // If our return type is an unaliased bounded (w)string, we create + // an empty struct using the operation's flat name for the type, + // and use this type as the Arg_Traits<> template parameter. All + // this is necessary because there could be any number of such + // return types, all identical, in the same interface, valuetype, + // translation unit, or build, and we need a unique type for the + // Arg_Traits<> template parameter. + if (nt == AST_Decl::NT_string || nt == AST_Decl::NT_wstring) + { + AST_String *str = AST_String::narrow_from_decl (rt); + ACE_CDR::ULong bound = str->max_size ()->ev ()->u.ulval; + + if (bound > 0) + { + TAO_OutStream *os = this->ctx_->stream (); + + *os << be_nl << be_nl << "// TAO_IDL - Generated from" << be_nl + << "// " << __FILE__ << ":" << __LINE__; + + bool wide = (str->width () != 1); + + *os << be_nl << be_nl; + + bool const skel = + (this->ctx_->state () == TAO_CodeGen::TAO_ROOT_SS); + + // Avoid generating a duplicate structure in the skeleton + // when generating Arg_Traits<> for ThruPOA and direct + // collocation code. + if (!skel + || (skel && ACE_OS::strlen (this->S_) != 0)) + { + *os << "struct " << node->flat_name () << " {};" + << be_nl << be_nl; + } + + *os << "template<>" << be_nl + << "class " + << this->S_ << "Arg_Traits<" + << node->flat_name () + << ">" << be_idt_nl + << ": public" << be_idt << be_idt_nl + << "BD_String_" << this->S_ << "Arg_Traits_T<" << be_nl + << "CORBA::" << (wide ? "W" : "") << "String_var," << be_nl + << bound << "," << be_nl + << this->insert_policy() << " <" << be_idt_nl + << "ACE_OutputCDR::from_" << (wide ? "w" : "") << "string" << be_uidt_nl + << ">" + << be_uidt_nl + << ">" + << be_uidt << be_uidt << be_uidt_nl + << "{" << be_nl + << "};"; + } + } + + // This will catch (in visit_argument() below) any parameters that + // are unaliased, bounded (w)strings. + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_arg_traits::" + "visit_operation - visit scope failed\n"), + -1); + } + + this->generated (node, true); + return 0; +} + +int +be_visitor_arg_traits::visit_attribute (be_attribute *node) +{ + if (this->ctx_->alias () != 0 || this->generated (node)) + { + return 0; + } + + AST_String *st = AST_String::narrow_from_decl (node->field_type ()); + + if (st == 0) + { + return 0; + } + + ACE_CDR::ULong bound = st->max_size ()->ev ()->u.ulval; + + if (bound == 0) + { + return 0; + } + + TAO_OutStream *os = this->ctx_->stream (); + + *os << be_nl << be_nl << "// TAO_IDL - Generated from" << be_nl + << "// " << __FILE__ << ":" << __LINE__; + + bool wide = (st->width () != 1); + + // It is legal IDL to declare a bounded (w)string as an operation + // parameter type. There could be any number of identical + // declarations in the same build, translation unit, or even in + // the same operation, so we use the argument's flat name to + // declare an empty struct, and use that struct as the template + // parameter for Arg_Traits<>. + + *os << be_nl; + + bool const skel = + (this->ctx_->state () == TAO_CodeGen::TAO_ROOT_SS); + + // Avoid generating a duplicate structure in the skeleton when + // generating Arg_Traits<> for ThruPOA and direct collocation code. + if (!skel + || (skel && ACE_OS::strlen (this->S_) != 0)) + { + *os << "struct " << node->flat_name () << " {};" + << be_nl << be_nl; + } + + *os << "template<>" << be_nl + << "class " + << this->S_ << "Arg_Traits<" + << node->flat_name () + << ">" << be_idt_nl + << ": public" << be_idt << be_idt_nl + << "BD_String_" << this->S_ << "Arg_Traits_T<" << be_nl + << "CORBA::" << (wide ? "W" : "") << "String_var," << be_nl + << bound << "," << be_nl + << this->insert_policy() << " <" << be_idt_nl + << "ACE_OutputCDR::from_" << (wide ? "w" : "") << "string" << be_uidt_nl + << ">" + << be_uidt_nl + << ">" + << be_uidt << be_uidt << be_uidt_nl + << "{" << be_nl + << "};"; + + this->generated (node, true); + return 0; +} + +int +be_visitor_arg_traits::visit_argument (be_argument *node) +{ + if (this->ctx_->alias () != 0 || this->generated (node)) + { + return 0; + } + + AST_Type *bt = node->field_type (); + AST_Decl::NodeType nt = bt->node_type (); + + // We are interested here only in unaliased, bounded + // (w)strings. + + if (nt != AST_Decl::NT_string && nt != AST_Decl::NT_wstring) + { + return 0; + } + + be_string *st = be_string::narrow_from_decl (bt); + ACE_CDR::ULong bound = st->max_size ()->ev ()->u.ulval; + + if (bound == 0) + { + return 0; + } + + TAO_OutStream *os = this->ctx_->stream (); + + *os << be_nl << be_nl << "// TAO_IDL - Generated from" << be_nl + << "// " << __FILE__ << ":" << __LINE__; + + bool wide = (st->width () != 1); + + // It is legal IDL to declare a bounded (w)string as an operation + // parameter type. There could be any number of identical + // declarations in the same build, translation unit, or even in + // the same operation, so we use the argument's flat name to + // declare an empty struct, and use that struct as the template + // parameter for Arg_Traits<>. + *os << be_nl << be_nl; + + bool const skel = + (this->ctx_->state () == TAO_CodeGen::TAO_ROOT_SS); + + AST_Decl *op = ScopeAsDecl (node->defined_in ()); + AST_Decl *intf = ScopeAsDecl (op->defined_in ()); + ACE_CString arg_flat_name (intf->flat_name ()); + arg_flat_name += '_'; + arg_flat_name += op->local_name ()->get_string (); + arg_flat_name += '_'; + arg_flat_name += node->local_name ()->get_string (); + + // Avoid generating a duplicate structure in the skeleton when + // generating Arg_Traits<> for ThruPOA and direct collocation code. + if (!skel + || (skel && ACE_OS::strlen (this->S_) != 0)) + { + *os << "struct " << arg_flat_name.c_str () << " {};" + << be_nl << be_nl; + } + + *os << "template<>" << be_nl + << "class " + << this->S_ << "Arg_Traits<" + << arg_flat_name.c_str () + << ">" << be_idt_nl + << ": public" << be_idt << be_idt_nl + << "BD_String_" << this->S_ << "Arg_Traits_T<" << be_nl + << "CORBA::" << (wide ? "W" : "") << "String_var," << be_nl + << bound << "," << be_nl + << this->insert_policy() << " <" << be_idt_nl + << "ACE_OutputCDR::from_" << (wide ? "w" : "") << "string" << be_uidt_nl + << ">" + << be_uidt_nl + << ">" + << be_uidt << be_uidt << be_uidt_nl + << "{" << be_nl + << "};"; + + this->generated (node, true); + return 0; +} + +int +be_visitor_arg_traits::visit_sequence (be_sequence *node) +{ + if (this->generated (node) || !node->seen_in_operation ()) + { + return 0; + } + + TAO_OutStream *os = this->ctx_->stream (); + be_typedef *alias = this->ctx_->alias (); + + *os << be_nl << be_nl << "// TAO_IDL - Generated from" << be_nl + << "// " << __FILE__ << ":" << __LINE__; + + std::string guard_suffix = + std::string (this->S_) + std::string ("arg_traits"); + + // This should be generated even for imported nodes. The ifdef + // guard prevents multiple declarations. + os->gen_ifdef_macro (alias->flat_name (), guard_suffix.c_str (), false); + + *os << be_nl << be_nl + << "template<>" << be_nl + << "class " + << this->S_ << "Arg_Traits<" + << alias->name () << ">" << be_idt_nl + << ": public" << be_idt << be_idt_nl + << "Var_Size_" << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl + << alias->name () << "," << be_nl + << this->insert_policy() << " <" << alias->name () << ">" << be_uidt_nl + << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl + << "{" << be_nl + << "};"; + + os->gen_endif (); + + this->generated (node, true); + return 0; +} + +int +be_visitor_arg_traits::visit_string (be_string *node) +{ + if ((this->generated (node) && !this->ctx_->alias()) + || !node->seen_in_operation ()) + { + return 0; + } + + ACE_CDR::ULong bound = node->max_size ()->ev ()->u.ulval; + be_type *alias = this->ctx_->alias (); + + // Unbounded (w)string args are handled as a predefined type. + // Bounded (w)strings must come in as a typedef - they can't + // be used directly as arguments or return types. + if (bound == 0) + { + return 0; + } + + bool wide = (node->width () != 1); + + TAO_OutStream *os = this->ctx_->stream (); + + std::string guard_suffix = + std::string (this->S_) + std::string ("arg_traits"); + + // This should be generated even for imported nodes. The ifdef + // guard prevents multiple declarations. + + if (alias == 0) + { + os->gen_ifdef_macro (node->flat_name(), guard_suffix.c_str (), false); + } + else + { + // Form a unique macro name using the local name and the bound. + ACE_CDR::ULong l = bound; + int num_digits = 0; + + while (l > 0) + { + l /= 10 ; + ++num_digits ; + } + + size_t bound_length = num_digits + 1; + char* bound_string = 0; + ACE_NEW_RETURN (bound_string, char[bound_length], -1) ; + ACE_OS::sprintf (bound_string, "%lu", bound); + + size_t cat_length = ACE_OS::strlen (alias->local_name ()->get_string ()) + + ACE_OS::strlen (bound_string) + + 1; + char* cat_string = 0; + ACE_NEW_RETURN (cat_string, char[cat_length], -1) ; + ACE_OS::strcpy (cat_string, alias->local_name ()->get_string ()) ; + ACE_OS::strcat (cat_string, bound_string); + + os->gen_ifdef_macro (cat_string, guard_suffix.c_str (), false); + + delete [] cat_string; + delete [] bound_string; + } + + bool const skel = + (this->ctx_->state () == TAO_CodeGen::TAO_ROOT_SS); + + // Avoid generating a duplicate structure in the skeleton when + // generating Arg_Traits<> for ThruPOA and direct collocation code. + if (!skel + || (skel && ACE_OS::strlen (this->S_) != 0)) + { + // A workaround 'dummy' type, since bounded (w)strings are all + // generated as typedefs of (w)char *. + *os << be_nl << be_nl + << "struct "; + + if (alias == 0) + { + *os << node->flat_name (); + } + else + { + *os << alias->local_name () << "_" << bound; + } + + *os << " {};"; + } + + *os << be_nl << be_nl + << "template<>" << be_nl + << "class " + << this->S_ << "Arg_Traits<"; + + if (0 == alias) + { + *os << node->flat_name (); + } + else + { + *os << alias->local_name () << "_" << bound; + } + + *os << ">" << be_idt_nl + << ": public" << be_idt << be_idt_nl + << "BD_String_" << this->S_ << "Arg_Traits_T<" + << be_idt << be_idt_nl + << "CORBA::" << (wide ? "W" : "") << "String_var," << be_nl + << bound << "," << be_nl + << this->insert_policy() << " <" << be_idt << be_idt_nl + << "ACE_OutputCDR::from_" << (wide ? "w" : "") << "string" << be_uidt_nl + << ">" + << be_uidt << be_uidt_nl + << ">" + << be_uidt << be_uidt << be_uidt << be_uidt_nl + << "{" << be_nl + << "};"; + + os->gen_endif (); + + this->generated (node, true); + return 0; +} + +int +be_visitor_arg_traits::visit_array (be_array *node) +{ + if (this->generated (node) || !node->seen_in_operation ()) + { + return 0; + } + + TAO_OutStream *os = this->ctx_->stream (); + + // This should be generated even for imported nodes. The ifdef guard prevents + // multiple declarations. + ACE_CString suffix (this->S_); + suffix += "arg_traits"; + os->gen_ifdef_macro (node->flat_name (), suffix.c_str (), false); + + *os << be_nl << be_nl + << "template<>" << be_nl + << "class " + << this->S_ << "Arg_Traits<" + << node->name () << "_tag>" << be_idt_nl + << ": public" << be_idt << be_idt_nl; + + *os << (node->size_type () == AST_Type::FIXED ? "Fixed" : "Var") + << "_Array_" << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl + << node->name () + << (node->size_type () == AST_Type::VARIABLE ? "_out" : "_var") + << "," << be_nl; + + *os << node->name () << "_forany"; + + *os << "," << be_nl << this->insert_policy() << " <" << node->name () << "_forany" << ">"; + + *os << be_uidt_nl + << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl + << "{" << be_nl + << "};"; + + os->gen_endif (); + + this->generated (node, true); + return 0; +} + +int +be_visitor_arg_traits::visit_enum (be_enum *node) +{ + if (this->generated (node) || !node->seen_in_operation ()) + { + return 0; + } + + TAO_OutStream *os = this->ctx_->stream (); + + *os << be_nl << be_nl << "// TAO_IDL - Generated from" << be_nl + << "// " << __FILE__ << ":" << __LINE__; + + std::string guard_suffix = + std::string (this->S_) + std::string ("arg_traits"); + + // This should be generated even for imported nodes. The ifdef + // guard prevents multiple declarations. + os->gen_ifdef_macro (node->flat_name (), guard_suffix.c_str (), false); + + *os << be_nl << be_nl + << "template<>" << be_nl + << "class " + << this->S_ << "Arg_Traits<" + << node->name () << ">" << be_idt_nl + << ": public" << be_idt << be_idt_nl; + + *os << "Basic_" << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl + << node->name () << "," << be_nl + << this->insert_policy() << " <" << node->name () << ">" << be_uidt_nl + << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl + << "{" << be_nl + << "};"; + + os->gen_endif (); + + this->generated (node, true); + return 0; +} + +int +be_visitor_arg_traits::visit_structure (be_structure *node) +{ + if (this->generated (node) || !node->seen_in_operation ()) + { + return 0; + } + + // This should be generated even for imported nodes. The ifdef guard prevents + // multiple declarations. + TAO_OutStream *os = this->ctx_->stream (); + + *os << be_nl << be_nl << "// TAO_IDL - Generated from" << be_nl + << "// " << __FILE__ << ":" << __LINE__; + + std::string guard_suffix = + std::string (this->S_) + std::string ("arg_traits"); + + // This should be generated even for imported nodes. The ifdef + // guard prevents multiple declarations. + os->gen_ifdef_macro (node->flat_name (), guard_suffix.c_str (), false); + + *os << be_nl << be_nl + << "template<>" << be_nl + << "class " + << this->S_ << "Arg_Traits<" + << node->name () << ">" << be_idt_nl + << ": public" << be_idt << be_idt_nl; + + *os << (node->size_type () == AST_Type::FIXED ? "Fixed" : "Var") + << "_Size_" << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl; + + *os << node->name () << "," << be_nl << this->insert_policy() << " <" << node->name () << ">" << be_uidt_nl + << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl + << "{" << be_nl + << "};"; + + os->gen_endif (); + + /* Set this before visiting the scope so things like + + interface foo + { + struct bar + { + .... + foo foo_member; + }; + + void op (in bar inarg); + }; + + will not cause infinite recursion in this visitor. + */ + + this->generated (node, true); + + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_arg_traits::" + "visit_structure - visit scope failed\n"), + -1); + } + + return 0; +} + +int +be_visitor_arg_traits::visit_field (be_field *node) +{ + be_type *bt = be_type::narrow_from_decl (node->field_type ()); + + if (!bt) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_arg_traits::" + "visit_field - " + "Bad field type\n"), + -1); + } + + // Valuetypes may not be *declared* in a field, so this will + // get handled elsewhere, and will also avoid nested valuetype + // recursion. So we set the field node as processed (the + // field *type* may not have been reached yet) and return. + AST_Decl::NodeType nt = bt->base_node_type (); + + if (nt == AST_Decl::NT_valuetype || nt == AST_Decl::NT_eventtype) + { + node->cli_traits_gen (true); + return 0; + } + + if (bt->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_arg_traits::" + "visit_field - " + "codegen for field type failed\n"), + -1); + } + + this->generated (node, true); + this->generated (bt, true); + return 0; +} + +int +be_visitor_arg_traits::visit_union (be_union *node) +{ + if (this->generated (node) || !node->seen_in_operation ()) + { + return 0; + } + + // This should be generated even for imported nodes. The ifdef guard prevents + // multiple declarations. + TAO_OutStream *os = this->ctx_->stream (); + + *os << be_nl << be_nl << "// TAO_IDL - Generated from" << be_nl + << "// " << __FILE__ << ":" << __LINE__; + + std::string guard_suffix = + std::string (this->S_) + std::string ("arg_traits"); + + // This should be generated even for imported nodes. The ifdef + // guard prevents multiple declarations. + os->gen_ifdef_macro (node->flat_name (), guard_suffix.c_str (), false); + + *os << be_nl << be_nl + << "template<>" << be_nl + << "class " + << this->S_ << "Arg_Traits<" + << node->name () << ">" << be_idt_nl + << ": public" << be_idt << be_idt_nl; + + *os << (node->size_type () == AST_Type::FIXED ? "Fixed" : "Var") + << "_Size_" << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl + << node->name () << "," << be_nl << this->insert_policy() << " <" + << node->name () << ">"; + + *os << be_uidt_nl + << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl + << "{" << be_nl + << "};"; + + os->gen_endif (); + + /* Set this before visiting the scope so things like + + interface foo + { + struct bar + { + .... + foo foo_member; + }; + + void op (in bar inarg); + }; + + will not cause infinite recursion in this visitor. + */ + + this->generated (node, true); + + int status = this->visit_scope (node); + + if (status != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_arg_traits::" + "visit_union - visit scope failed\n"), + -1); + } + + return 0; +} + +int +be_visitor_arg_traits::visit_union_branch (be_union_branch *node) +{ + be_type *bt = be_type::narrow_from_decl (node->field_type ()); + + if (!bt) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_arg_traits::" + "visit_union_branch - " + "Bad union_branch type\n"), + -1); + } + + if (bt->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_arg_traits::" + "visit_union_branch - " + "codegen for union_branch type failed\n"), + -1); + } + + this->generated (node, true); + return 0; +} + +int +be_visitor_arg_traits::visit_typedef (be_typedef *node) +{ + if (this->generated (node) || !node->seen_in_operation ()) + { + return 0; + } + + this->ctx_->alias (node); + + // Make a decision based on the primitive base type. + be_type *bt = node->primitive_base_type (); + + // We can't set seen_in_operation_ for the base type + // in the be_typedef operation, since valuetype OBV + // constructor code may reset it to FALSE, and the base + // type may be used unaliased in another arg somewhere. + // So we just set it to TRUE here, since we know it + // has to be TRUE at this point. We also set the + // 'generated' flag to false if the original value + // of 'seen_in_operation' was false, since the base + // type could have been processed already, as a member + // for example, before the typedef was seen, which + // would short-circuit things. + if (!bt->seen_in_operation ()) + { + bt->seen_in_operation (true); + this->generated (bt, false); + } + + if (!bt || (bt->accept (this) == -1)) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_arg_traits::" + "visit_typedef - " + "Bad primitive type\n"), + -1); + } + + this->ctx_->alias (0); + this->generated (node, true); + return 0; +} + +bool +be_visitor_arg_traits::generated (be_decl *node) const +{ + if (ACE_OS::strcmp (this->S_, "") == 0) + { + switch (this->ctx_->state ()) + { + case TAO_CodeGen::TAO_ROOT_CS: + return node->cli_arg_traits_gen (); + case TAO_CodeGen::TAO_ROOT_SS: + return node->srv_arg_traits_gen (); + default: + return 0; + } + } + + return node->srv_sarg_traits_gen (); +} + +void +be_visitor_arg_traits::generated (be_decl *node, + bool val) +{ + if (ACE_OS::strcmp (this->S_, "") == 0) + { + switch (this->ctx_->state ()) + { + case TAO_CodeGen::TAO_ROOT_CS: + node->cli_arg_traits_gen (val); + return; + case TAO_CodeGen::TAO_ROOT_SS: + node->srv_arg_traits_gen (val); + return; + default: + return; + } + } + + node->srv_sarg_traits_gen (val); +} + +int +be_visitor_arg_traits::visit_component (be_component *node) +{ + return this->visit_interface (node); +} + +int +be_visitor_arg_traits::visit_component_fwd (be_component_fwd *node) +{ + return this->visit_interface_fwd (node); +} + +int +be_visitor_arg_traits::visit_home (be_home *node) +{ + return this->visit_interface (node); +} + +const char * +be_visitor_arg_traits::insert_policy (void) +{ + if (be_global->any_support ()) + { + return "TAO::Any_Insert_Policy_Stream"; + } + else + { + return "TAO::Any_Insert_Policy_Noop"; + } +} |