summaryrefslogtreecommitdiff
path: root/TAO/TAO_IDL/be/be_visitor_argument/paramlist.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/TAO_IDL/be/be_visitor_argument/paramlist.cpp')
-rw-r--r--TAO/TAO_IDL/be/be_visitor_argument/paramlist.cpp237
1 files changed, 237 insertions, 0 deletions
diff --git a/TAO/TAO_IDL/be/be_visitor_argument/paramlist.cpp b/TAO/TAO_IDL/be/be_visitor_argument/paramlist.cpp
new file mode 100644
index 00000000000..e8f10292638
--- /dev/null
+++ b/TAO/TAO_IDL/be/be_visitor_argument/paramlist.cpp
@@ -0,0 +1,237 @@
+//
+// $Id$
+//
+
+// ============================================================================
+//
+// = LIBRARY
+// TAO IDL
+//
+// = FILENAME
+// paramlist.cpp
+//
+// = DESCRIPTION
+// Visitor that generates the Dyanmic::ParameterList
+//
+// = AUTHOR
+// Kirthika Parameswaran <kirthika@cs.wustl.edu>
+// Ossama Othman <ossama@uci.edu>
+//
+// ============================================================================
+
+ACE_RCSID (be_visitor_argument,
+ paramlist,
+ "$Id$")
+
+
+// ************************************************************
+// be_visitor_args_paramlist for parameter list in method declarations and
+// definitions
+// ************************************************************
+
+be_visitor_args_paramlist::be_visitor_args_paramlist (be_visitor_context *ctx)
+ : be_visitor_args (ctx)
+{
+}
+
+be_visitor_args_paramlist::~be_visitor_args_paramlist (void)
+{
+}
+
+int be_visitor_args_paramlist::visit_argument (be_argument *node)
+{
+ // Get output stream.
+ TAO_OutStream *os = this->ctx_->stream ();
+
+ // Save the argument node.
+ this->ctx_->node (node);
+
+ // We do not put "out" arguments into the arglist.
+ if (this->direction () == AST_Argument::dir_OUT)
+ {
+ return 0;
+ }
+
+ // Retrieve the type.
+ be_type *bt = be_type::narrow_from_decl (node->field_type ());
+
+ // If node is typedef'd, we must strip it off.
+ if (bt->node_type () == AST_Decl::NT_typedef)
+ {
+ be_typedef *td = be_typedef::narrow_from_decl (bt);
+ bt = td->primitive_base_type ();
+ }
+
+ if (!bt)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "be_visitor_args_arglist::"
+ "visit_argument - "
+ "Bad argument type\n"),
+ -1);
+ }
+
+ // Generate valuetype check: this hack is needed as there is no
+ // available way to check for valuetype type.
+ // Any operators for valuetypes arent there so we dont add it to the
+ // paramlist.
+ if (bt->node_type () == AST_Decl::NT_interface)
+ {
+ be_valuetype *vt = be_valuetype::narrow_from_decl (node->field_type ());
+
+ // @@ NOTE: If this check is removed, and insertion operators
+ // for valuetypes are implemented, don't forget to also
+ // remove the same valuetype check in
+ // be_visitor_operation::count_non_out_parameters().
+
+ // If it is a valuetype just return.
+ if (vt)
+ {
+ return 0;
+ }
+ }
+
+ // Amazed by the zillion os operators below? Its just to combat
+ // side effects functions like type_name() have on the os stream.
+ // This was causing a problem with the stubs not been generated accurately
+ // on Linux using egcs.
+ if (bt->node_type () == AST_Decl::NT_array)
+ {
+ *os << this->type_name (bt, "_forany");
+ *os << " _tao_forany_" << node->local_name () << " (";
+ *os << this->type_name (bt, "_dup");
+ *os << " (";
+
+ if (this->direction () != AST_Argument::dir_IN)
+ {
+ *os << "(const ::" << bt->name () << "_slice *) ";
+ }
+
+ *os << "this->";
+ *os << node->local_name () << "_));" << be_nl;
+ *os << "(*parameter_list)[len].argument <<= _tao_forany_" ;
+ *os << node->local_name () << ";" << be_nl;
+ }
+ else
+ {
+ *os << "(*parameter_list)[len].argument <<= ";
+ // Insertion into an Any has some special cases which need to be
+ // dealt with.
+
+ switch (bt->node_type ())
+ {
+ case AST_Decl::NT_pre_defined:
+ case AST_Decl::NT_string:
+ case AST_Decl::NT_wstring:
+ if (bt->accept (this) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "be_visitor_args_paramlist::"
+ "visit_argument - "
+ "cannot accept visitor\n"),
+ -1);
+ }
+ break;
+
+ default:
+ *os << " this->" << node->local_name () << "_;";
+
+ }
+ }
+
+ *os << be_nl;
+
+ // Set the appropriate mode for each parameter.
+ switch (node->direction ())
+ {
+ case AST_Argument::dir_IN:
+ *os << "(*parameter_list)[len].mode = ::CORBA::PARAM_IN;" << be_nl;
+ break;
+ case AST_Argument::dir_INOUT:
+ *os << "(*parameter_list)[len].mode = ::CORBA::PARAM_INOUT;" << be_nl;
+ break;
+ case AST_Argument::dir_OUT:
+ *os << "(*parameter_list)[len].mode = ::CORBA::PARAM_OUT;" << be_nl;
+ break;
+ default:
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_visitor_args_paramlist::"
+ "visit_argument - "
+ "Bad context\n"),
+ -1);
+ }
+
+ *os << "len++;" << be_nl;
+
+
+ return 0;
+}
+
+int
+be_visitor_args_paramlist::visit_string (be_string *node)
+{
+ // Get output stream.
+ TAO_OutStream *os = this->ctx_->stream ();
+
+ // Get the argument.
+ be_argument *arg = this->ctx_->be_node_as_argument ();
+
+ // We need to make a distinction between bounded and unbounded strings.
+ if (node->max_size ()->ev ()->u.ulval != 0)
+ {
+ // Bounded strings.
+ if (node->width () == (long) sizeof (char))
+ {
+ *os << "::ACE_OutputCDR::from_string ((char *)";
+ }
+ else
+ {
+ *os << "::ACE_OutputCDR::from_wstring ((CORBA::WChar *)";
+ }
+
+ *os << arg->local_name () << "_, "
+ << node->max_size ()->ev ()->u.ulval
+ << ");";
+ }
+ else
+ {
+ *os << arg->local_name () <<"_;";
+ }
+
+ return 0;
+}
+
+int
+be_visitor_args_paramlist::visit_predefined_type (be_predefined_type *node)
+{
+ // Get output stream.
+ TAO_OutStream *os = this->ctx_->stream ();
+
+ // Get the argument.
+ be_argument *arg = this->ctx_->be_node_as_argument ();
+
+ switch (node->pt ())
+ {
+ case AST_PredefinedType::PT_boolean:
+ *os << "::ACE_OutputCDR::from_boolean (this->";
+ *os << arg->local_name () << "_);";
+ break;
+ case AST_PredefinedType::PT_char:
+ *os << "::ACE_OutputCDR::from_char (this->";
+ *os << arg->local_name () << "_);";
+ break;
+ case AST_PredefinedType::PT_wchar:
+ *os << "::ACE_OutputCDR::from_wchar (this->";
+ *os << arg->local_name () << "_);";
+ break;
+ case AST_PredefinedType::PT_octet:
+ *os << "::ACE_OutputCDR::from_octet (this->";
+ *os << arg->local_name () << "_);";
+ break;
+ default:
+ *os << arg->local_name () << "_;";
+ break;
+ }
+
+ return 0;
+}