summaryrefslogtreecommitdiff
path: root/TAO/TAO_IDL/be/be_interface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'TAO/TAO_IDL/be/be_interface.cpp')
-rw-r--r--TAO/TAO_IDL/be/be_interface.cpp721
1 files changed, 502 insertions, 219 deletions
diff --git a/TAO/TAO_IDL/be/be_interface.cpp b/TAO/TAO_IDL/be/be_interface.cpp
index 2de95f3ee1f..d75afa50673 100644
--- a/TAO/TAO_IDL/be/be_interface.cpp
+++ b/TAO/TAO_IDL/be/be_interface.cpp
@@ -19,6 +19,7 @@
#include "idl.h"
#include "idl_extern.h"
+#include "be_visitor_interface.h"
#include "be.h"
/*
@@ -28,7 +29,9 @@
// default constructor
be_interface::be_interface (void)
: full_skel_name_ (0),
- skel_count_ (0)
+ skel_count_ (0),
+ full_coll_name_ (0),
+ local_coll_name_ (0)
{
this->size_type (be_decl::VARIABLE); // always the case
}
@@ -40,11 +43,124 @@ be_interface::be_interface (UTL_ScopedName *n, AST_Interface **ih, long nih,
AST_Decl (AST_Decl::NT_interface, n, p),
UTL_Scope (AST_Decl::NT_interface),
full_skel_name_ (0),
- skel_count_ (0)
+ skel_count_ (0),
+ full_coll_name_ (0),
+ local_coll_name_ (0)
{
this->size_type (be_decl::VARIABLE); // always the case
}
+be_interface::~be_interface (void)
+{
+ if (this->full_skel_name_ != 0)
+ {
+ delete[] this->full_skel_name_;
+ this->full_skel_name_ = 0;
+ }
+ if (this->full_coll_name_ != 0)
+ {
+ delete[] this->full_coll_name_;
+ this->full_coll_name_ = 0;
+ }
+ if (this->local_coll_name_ != 0)
+ {
+ delete[] this->local_coll_name_;
+ this->local_coll_name_ = 0;
+ }
+}
+
+// compute stringified fully qualified collocated class name.
+void
+be_interface::compute_coll_name (void)
+{
+ if (this->full_coll_name_ != 0)
+ return;
+
+ const char collocated[] = "_tao_collocated_";
+ const char poa[] = "POA_";
+ // Reserve enough room for the "POA_" prefix, the "_tao_collocated_"
+ // prefix and the local name and the (optional) "::"
+ int namelen = sizeof (collocated) + sizeof (poa);
+
+ UTL_IdListActiveIterator *i;
+ ACE_NEW (i, UTL_IdListActiveIterator (this->name ()));
+ while (!i->is_done ())
+ {
+ // reserve 2 characters for "::".
+ namelen += ACE_OS::strlen (i->item ()->get_string ()) + 2;
+ i->next ();
+ }
+ delete i;
+
+ ACE_NEW (this->full_coll_name_, char[namelen+1]);
+ this->full_coll_name_[0] = 0; // null terminate the string...
+
+ // Iterate again....
+ ACE_NEW (i, UTL_IdListActiveIterator (this->name ()));
+
+ // Only the first component get the "POA_" preffix.
+ int poa_added = 0;
+ while (!i->is_done ())
+ {
+ const char* item = i->item ()->get_string ();
+
+ // Increase right away, so we can test for the final component
+ // in the loop.
+ i->next ();
+
+ // We add the POA_ preffix only if the first component is not
+ // the global scope...
+ if (ACE_OS::strcmp (item, "") != 0)
+ {
+ if (!i->is_done ())
+ {
+ // We only add the POA_ preffix if there are more than
+ // two components in the name, in other words, if the
+ // class is inside some scope.
+ if (!poa_added)
+ {
+ ACE_OS::strcat (this->full_coll_name_, poa);
+ poa_added = 1;
+ }
+ ACE_OS::strcat (this->full_coll_name_, item);
+ ACE_OS::strcat (this->full_coll_name_, "::");
+ }
+ else
+ {
+ ACE_OS::strcat (this->full_coll_name_, collocated);
+ ACE_OS::strcat (this->full_coll_name_, item);
+ }
+ }
+ }
+ delete i;
+
+ // Compute the local name for the collocated class.
+ int localen = sizeof (collocated);
+ localen += ACE_OS::strlen (this->local_name ()->get_string ());
+ ACE_NEW (this->local_coll_name_, char[localen]);
+ ACE_OS::strcpy(this->local_coll_name_, collocated);
+ ACE_OS::strcat(this->local_coll_name_,
+ this->local_name ()->get_string ());
+}
+
+const char*
+be_interface::full_coll_name (void) const
+{
+ if (this->full_coll_name_ == 0)
+ ACE_const_cast(be_interface*, this)->compute_coll_name ();
+
+ return this->full_coll_name_;
+}
+
+const char*
+be_interface::local_coll_name (void) const
+{
+ if (this->local_coll_name_ == 0)
+ ACE_const_cast(be_interface*, this)->compute_coll_name ();
+
+ return this->local_coll_name_;
+}
+
// compute stringified fully scoped skel name
void
be_interface::compute_fullskelname (void)
@@ -126,22 +242,21 @@ be_interface::full_skel_name (void)
// ----------------------------------------
// generate the client header
-int be_interface::gen_client_header (void)
+int
+be_interface::gen_client_header (void)
{
- TAO_OutStream *ch; // output stream
- long i; // loop index
- TAO_NL nl; // end line
-
-
if (!this->cli_hdr_gen_) // not already generated
{
+ long i; // loop index
+ TAO_NL nl; // end line
+
// retrieve a singleton instance of the code generator
TAO_CodeGen *cg = TAO_CODEGEN::instance ();
cg->push (TAO_CodeGen::TAO_INTERFACE_CH); // set the current code
// generation state
- ch = cg->client_header ();
+ TAO_OutStream *ch = cg->client_header ();
// == STEP 1: generate the class name and class names we inherit ==
ch->indent (); // start with whatever indentation level we are at
@@ -156,7 +271,7 @@ int be_interface::gen_client_header (void)
*ch << "class " << this->local_name () << ";" << nl;
// generate the _ptr declaration
*ch << "typedef " << this->local_name () << " *" << this->local_name ()
- << "_ptr;" << nl;
+ << "_ptr;" << nl;
ch->gen_endif ();
@@ -165,11 +280,11 @@ int be_interface::gen_client_header (void)
// generate the _var declaration
if (this->gen_var_defn () == -1)
- {
- ACE_ERROR ((LM_ERROR,
- "be_interface - error generating _var definition\n"));
- return -1;
- }
+ {
+ ACE_ERROR ((LM_ERROR,
+ "be_interface - error generating _var definition\n"));
+ return -1;
+ }
ch->gen_endif ();
// generate the ifdef macro for the _out class
@@ -177,11 +292,11 @@ int be_interface::gen_client_header (void)
// generate the _out declaration - ORBOS/97-05-15 pg 16-20 spec
if (this->gen_out_defn () == -1)
- {
- ACE_ERROR ((LM_ERROR,
- "be_interface - error generating _var definition\n"));
- return -1;
- }
+ {
+ ACE_ERROR ((LM_ERROR,
+ "be_interface - error generating _var definition\n"));
+ return -1;
+ }
// generate the endif macro
ch->gen_endif ();
@@ -230,49 +345,55 @@ int be_interface::gen_client_header (void)
ch->incr_indent ();
// generate the static _duplicate, _narrow, and _nil operations
*ch << "// the static operations" << nl;
- *ch << "static " << local_name () << "_ptr " << "_duplicate (" <<
- local_name () << "_ptr obj);" << nl;
- *ch << "static " << local_name () << "_ptr " << "_narrow (" <<
- "CORBA::Object_ptr obj, CORBA::Environment &env);" << nl;
- *ch << "static " << local_name () << "_ptr " << "_nil (" <<
- "void);" << nl;
+ *ch << "static " << this->local_name () << "_ptr " << "_duplicate ("
+ << this->local_name () << "_ptr obj);" << nl;
+ *ch << "static " << this->local_name () << "_ptr " << "_narrow ("
+ << "CORBA::Object_ptr obj, CORBA::Environment &env);" << nl;
+ *ch << "static " << this->local_name () << "_ptr "
+ << "_nil (void);" << nl;
// generate a TAO-specific _bind method similar to what Orbix and VisiBroker
// have
*ch << "static " << this->local_name () << "_ptr _bind (const char *host, "
- << "CORBA::UShort port, const char *key, CORBA::Environment &env);\n\n";
+ << "CORBA::UShort port, const char *key, CORBA::Environment &env);\n\n";
+
+ // the _is_a method
+ ch->indent ();
+ *ch << "virtual CORBA::Boolean _is_a (const CORBA::Char *type_id, "
+ << "CORBA::Environment &env);\n" << be_nl
+ << "// = user methods\n";
// generate code for the interface definition by traversing thru the
// elements of its scope. We depend on the front-end to have made sure
// that only legal syntactic elements appear in our scope.
- if (be_scope::gen_client_header () == -1)
- {
- ACE_ERROR ((LM_ERROR, "be_interface::gen_client_header\n"));
- ACE_ERROR ((LM_ERROR, "Scope code generation failure\n"));
- return -1;
- }
-
- // the _is_a method
- ch->indent ();
- *ch << "virtual CORBA::Boolean _is_a (const CORBA::Char *type_id, " <<
- "CORBA::Environment &env);\n";
+ if (this->be_scope::gen_client_header () == -1)
+ {
+ ACE_ERROR ((LM_ERROR, "be_interface::gen_client_header\n"));
+ ACE_ERROR ((LM_ERROR, "Scope code generation failure\n"));
+ return -1;
+ }
// generate the "protected" constructor so that users cannot instantiate
// us
- ch->decr_indent ();
- *ch << "protected:\n";
- ch->incr_indent ();
- *ch << local_name () << " (void); // default constructor" << nl;
- *ch << local_name () << " (STUB_Object *objref);" << nl;
- *ch << "virtual ~" << local_name () << " (void);\n";
+ *ch << be_uidt_nl
+ << "protected:" << be_idt_nl
+ << this->local_name () << " (" << be_idt << be_idt_nl
+ << "STUB_Object *objref = 0," << be_nl
+ << "TAO_ServantBase *servant = 0," << be_nl
+ << "CORBA::Boolean collocated = CORBA::B_FALSE" << be_uidt_nl
+ << ");\n" << be_uidt;
ch->decr_indent ();
+ // dtor is public...
+ *ch << "public:" << be_idt_nl
+ << "virtual ~" << this->local_name () << " (void);" << be_uidt_nl;
+
// private copy constructor and assignment operator. These are not
// allowed, hence they are private.
*ch << "private:\n";
ch->incr_indent ();
- *ch << local_name () << " (const " << local_name () << "&);" << nl;
- *ch << "void operator= (const " << local_name () << "&);\n";
+ *ch << this->local_name () << " (const " << this->local_name () << "&);" << nl;
+ *ch << "void operator= (const " << this->local_name () << "&);\n";
ch->decr_indent ();
*ch << "};\n\n";
ch->gen_endif ();
@@ -281,19 +402,19 @@ int be_interface::gen_client_header (void)
// generate the typecode decl. If we are in the outermost scope, our typecode
// decl is extern
if (this->is_nested ())
- {
- // we have a scoped name
- ch->indent ();
- *ch << "static CORBA::TypeCode_ptr " << this->tc_name
- ()->last_component () << ";\n\n";
- }
+ {
+ // we have a scoped name
+ ch->indent ();
+ *ch << "static CORBA::TypeCode_ptr " << this->tc_name
+ ()->last_component () << ";\n\n";
+ }
else
- {
- // we are in the ROOT scope
- ch->indent ();
- *ch << "extern CORBA::TypeCode_ptr " << this->tc_name
- ()->last_component () << ";\n\n";
- }
+ {
+ // we are in the ROOT scope
+ ch->indent ();
+ *ch << "extern CORBA::TypeCode_ptr " << this->tc_name
+ ()->last_component () << ";\n\n";
+ }
cg->pop ();
this->cli_hdr_gen_ = I_TRUE;
@@ -301,28 +422,89 @@ int be_interface::gen_client_header (void)
return 0;
}
-int be_interface::gen_client_stubs (void)
+// Generates the client-side inline functions
+int
+be_interface::gen_client_inline (void)
{
- TAO_OutStream *cs; // output stream
- long i; // loop index
TAO_NL nl; // end line
- // Macro to avoid "warning: unused parameter" type warning.
- ACE_UNUSED_ARG (i);
+ // retrieve a singleton instance of the code generator
+ TAO_CodeGen *cg = TAO_CODEGEN::instance ();
+
+ TAO_OutStream *ci = cg->client_inline ();
+ ci->indent (); // start from the current indentation level
+
+ *ci << "ACE_INLINE" << nl;
+ *ci << this->name () << "::"
+ << this->local_name () << "(" << be_idt << be_idt_nl
+ << "STUB_Object *objref," << be_nl
+ << "TAO_ServantBase *servant," << be_nl
+ << "CORBA::Boolean collocated" << be_uidt_nl
+ << ")" << be_uidt_nl
+ << " : ACE_CORBA_1 (Object) (objref, servant, collocated)" << be_nl
+ << "{}" << be_nl << be_nl;
+
+ *ci << "ACE_INLINE" << nl;
+ *ci << this->name () << "::~" << this->local_name () <<
+ " (void) // destructor" << nl;
+ *ci << "{}\n\n";
+
+ // _nil method
+ *ci << "ACE_INLINE " << this->name () << "_ptr" << be_nl
+ << this->name () << "::_nil (void)" << be_nl
+ << "{" << be_idt_nl
+ << "return (" << this->name () << "_ptr)0;" << be_uidt_nl
+ << "}\n" << be_nl;
+
+ // generate the ifdefined macro for the _var type
+ ci->gen_ifdef_macro (this->flatname (), "_var");
+
+ if (this->gen_var_impl () == -1)
+ {
+ ACE_ERROR ((LM_ERROR, "be_interface: _var impl code gen failed\n"));
+ return -1;
+ }
+ ci->gen_endif ();
+
+ // generate the ifdefined macro for the _out type
+ ci->gen_ifdef_macro (this->flatname (), "_out");
+
+ if (this->gen_out_impl () == -1)
+ {
+ ACE_ERROR ((LM_ERROR, "be_interface: _out impl code gen failed\n"));
+ return -1;
+ }
+ ci->gen_endif ();
+
+ if (this->be_scope::gen_client_inline () == -1)
+ {
+ ACE_ERROR ((LM_ERROR, "be_interface: code gen failed for scope\n"));
+ return -1;
+ }
+
+ return 0;
+}
+
+
+// Generate the client-side stubs
+int
+be_interface::gen_client_stubs (void)
+{
+ TAO_NL nl; // end line
// retrieve a singleton instance of the code generator
TAO_CodeGen *cg = TAO_CODEGEN::instance ();
cg->push (TAO_CodeGen::TAO_INTERFACE_CS); // set the current code generation
// state
- cs = cg->client_stubs ();
+ TAO_OutStream *cs = cg->client_stubs ();
cs->indent (); // start with whatever indentation level we are at
// first generate the code for the static methods
// The _duplicate method
- *cs << name () << "_ptr " << name () << "::_duplicate (" <<
- name () << "_ptr obj)" << nl;
+ *cs << this->name () << "_ptr " << this->name () << "::_duplicate ("
+ << this->name () << "_ptr obj)" << nl;
*cs << "{\n";
cs->incr_indent ();
*cs << "if (!CORBA::is_nil (obj))\n";
@@ -335,17 +517,22 @@ int be_interface::gen_client_stubs (void)
*cs << "} // end of _duplicate" << nl << nl;
// The _narrow method
- *cs << name () << "_ptr " << name () <<
- "::_narrow (CORBA::Object_ptr obj, CORBA::Environment &env)" << nl;
- *cs << "{\n";
- cs->incr_indent ();
- *cs << "if (CORBA::is_nil (obj)) return " << this->name () << "::_nil ();" <<
- nl;
- *cs << "if (obj->_is_a (\"" << this->repoID () << "\", env))" << nl;
- *cs << "{\n";
- cs->incr_indent ();
+ *cs << this->name () << "_ptr " << this->name ()
+ << "::_narrow (" << be_idt << be_idt_nl
+ << "CORBA::Object_ptr obj," << be_nl
+ << "CORBA::Environment &env" << be_uidt_nl
+ << ")" << be_uidt_nl
+ << "{" << be_idt_nl
+ << "if (CORBA::is_nil (obj))" << be_idt_nl
+ << "return " << this->name () << "::_nil ();" << be_uidt_nl
+ << "if (!obj->_is_a (\"" << this->repoID () << "\", env))"
+ << be_idt_nl
+ << "return " << this->name () << "::_nil ();" << be_uidt_nl;
+
+ *cs << "if (!obj->_is_collocated () || !obj->_servant())" << be_nl
+ << "{" << be_idt_nl;
*cs << "STUB_Object *istub;" << nl;
- *cs << name () << "_ptr new_obj; // to be returned " << nl;
+ *cs << this->name () << "_ptr new_obj; // to be returned " << nl;
#if 0 // XXXASG - I was told that emitting this line of code is the root cause
// of all evil
*cs << "obj->Release ();" <<
@@ -361,23 +548,24 @@ int be_interface::gen_client_stubs (void)
*cs << "obj->Release (); " <<
"// need this since QueryIntf bumped our refcount" << nl;
#endif
- *cs << "new_obj = new " << name () << " (istub); " <<
- "// construct obj ref using the stub object" << nl;
+ *cs << "new_obj = new " << this->name () << " (istub); "
+ << "// construct obj ref using the stub object" << nl;
*cs << "return new_obj;\n";
cs->decr_indent ();
- *cs << "} // end of if" << nl;
- *cs << "return " << this->name () << "::_nil (); // _narrow failed\n";
- cs->decr_indent ();
- *cs << "} // end of _narrow" << nl << nl;
-
- // _nil method
- *cs << this->name () << "_ptr " << this->name () << "::_nil (void)" <<
- nl;
- *cs << "{\n";
- cs->incr_indent ();
- *cs << "return (" << name () << "_ptr)NULL;\n";
- cs->decr_indent ();
- *cs << "} // end of _nil" << nl << nl;
+ *cs << "} // end of if\n" << nl;
+
+ *cs << "STUB_Object *stub = obj->_servant ()->_create_stub (env);" << be_nl
+ << "if (env.exception () != 0)" << be_idt_nl
+ << "return " << this->name () << "::_nil ();" << be_uidt_nl
+ << "void* servant = obj->_servant ()->_downcast (\""
+ << this->repoID () << "\");" << be_nl
+ << "return new "
+ << this->full_coll_name () << "(" << be_idt << be_idt_nl
+ << "ACE_reinterpret_cast(" << this->full_skel_name ()
+ << "_ptr, servant)," << be_nl
+ << "stub" << be_uidt_nl
+ << ");" << be_uidt << be_uidt_nl
+ << "}" << be_nl << be_nl;
// the _bind method
*cs << this->name () << "_ptr " << this->name () << "::_bind (" <<
@@ -406,7 +594,7 @@ int be_interface::gen_client_stubs (void)
*cs << "}\n\n";
// generate code for the elements of the interface
- if (be_scope::gen_client_stubs () == -1)
+ if (this->be_scope::gen_client_stubs () == -1)
{
ACE_ERROR ((LM_ERROR, "be_interface::gen_client_stubs\n"));
ACE_ERROR ((LM_ERROR, "Scope code generation failure\n"));
@@ -416,7 +604,7 @@ int be_interface::gen_client_stubs (void)
// generate the is_a method
cs->indent ();
*cs << "CORBA::Boolean " << this->name () << "::_is_a (" <<
- "const CORBA::Char *value, CORBA::Environment &env)" << nl;
+ "const CORBA::Char *value, CORBA::Environment &_tao_environment)" << nl;
*cs << "{\n";
cs->incr_indent ();
*cs << "if (\n";
@@ -428,11 +616,11 @@ int be_interface::gen_client_stubs (void)
"inheritance graph failed\n"), -1);
}
cs->indent ();
- *cs << "(!ACE_OS::strcmp ((char *)value, CORBA::_tc_Object->id (env))))\n";
+ *cs << "(!ACE_OS::strcmp ((char *)value, CORBA::_tc_Object->id (_tao_environment))))\n";
*cs << "\treturn 1; // success using local knowledge\n";
cs->decr_indent ();
*cs << "else" << nl;
- *cs << "\treturn this->CORBA_Object::_is_a (value, env); // remote call\n";
+ *cs << "\treturn this->CORBA_Object::_is_a (value, _tao_environment); // remote call\n";
cs->decr_indent ();
*cs << "}\n\n";
@@ -503,30 +691,48 @@ int be_interface::gen_server_header (void)
<< "_ptr;" << nl;
// now generate the class definition
- *sh << "class " << namebuf << " : public virtual " << this->name ();
+ *sh << "class " << namebuf << " : ";
if (n_inherits () > 0) // this interface inherits from other interfaces
{
be_interface *intf;
- for (i = 0; i < n_inherits (); i++)
+ *sh << "public virtual ";
+ intf = be_interface::narrow_from_decl (inherits ()[0]);
+ *sh << intf->relative_skel_name (this->full_skel_name ());
+ for (i = 1; i < n_inherits (); i++)
{
*sh << ", public virtual ";
intf = be_interface::narrow_from_decl (inherits ()[i]);
- *sh << intf->relative_skel_name (this->full_skel_name ()); // dump
- // the
- // scoped
- // name
+ *sh << intf->relative_skel_name (this->full_skel_name ());
} // end of for loop
}
+ else
+ {
+ // We don't inherit from another user defined object, hence our
+ // base class is the ServantBase class.
+ *sh << " public virtual PortableServer::ServantBase";
+ }
*sh << nl;
*sh << "{" << nl;
*sh << "protected:\n";
sh->incr_indent ();
- *sh << namebuf << " (const char *obj_name = 0);" << nl;
- *sh << "virtual ~" << namebuf << " (void);\n";
+ *sh << namebuf << " (void);" << nl;
sh->decr_indent ();
*sh << "public:\n";
- sh->incr_indent (0);
+ sh->incr_indent ();
+ *sh << "virtual ~" << namebuf << " (void);\n";
+
+ sh->indent ();
+ *sh << "virtual CORBA::Boolean _is_a (" << be_idt << be_idt_nl
+ << "const char* logical_type_id," << be_nl
+ << "CORBA::Environment &_tao_environment" << be_uidt
+ << ");\n" << be_uidt;
+
+ sh->indent ();
+ *sh << "virtual void* _downcast (" << be_idt << be_idt_nl
+ << "const char* logical_type_id" << be_uidt_nl
+ << ");\n" << be_uidt;
+
// generate code for elements in the scope (e.g., operations)
if (be_scope::gen_server_header () == -1)
{
@@ -538,7 +744,7 @@ int be_interface::gen_server_header (void)
// add our _is_a method
sh->indent ();
*sh << "static void _is_a_skel (CORBA::ServerRequest &req, " <<
- "void *obj, void *context, CORBA::Environment &env);\n\n";
+ "void *obj, void *context, CORBA::Environment &_tao_enviroment);\n\n";
// generate skeletons for operations of our base classes. These skeletons
// just cast the pointer to the appropriate type before invoking the call
@@ -551,11 +757,25 @@ int be_interface::gen_server_header (void)
// add the dispatch method
sh->indent ();
- *sh << "virtual void dispatch (CORBA::ServerRequest &req, " <<
- "void *context, CORBA::Environment &env);" << nl;
+ *sh << "virtual void _dispatch (CORBA::ServerRequest &req, " <<
+ "void *context, CORBA::Environment &env);\n\n";
+
+ // Print out the _this() method.
+ sh->indent ();
+ *sh << this->name () << " *_this (CORBA::Environment &_tao_environment);\n";
+
+ sh->indent ();
+ *sh << "virtual const char* _interface_repository_id"
+ << " (void) const;\n";
+
sh->decr_indent ();
+
*sh << "};\n\n";
+ be_visitor_collocated_sh visitor;
+ this->accept (&visitor);
+ *sh << "\n";
+
cg->pop ();
return 0;
}
@@ -593,39 +813,19 @@ int be_interface::gen_server_skeletons (void)
{
// we are outermost. So the POA_ prefix is prepended to our name
*ss << this->full_skel_name () << "::POA_" << this->local_name () <<
- " (const char *obj_name)" << nl;
+ " (void)" << nl;
}
else
{
// the POA_ prefix is prepended to our outermost module name
*ss << this->full_skel_name () << "::" << this->local_name () <<
- " (const char *obj_name)" << nl;
+ " (void)" << nl;
}
- *ss << "{\n";
- ss->incr_indent ();
- // code for the skeleton constructor
- *ss << "const CORBA::String repoID = \"" << this->repoID () << "\"; // repository ID" << nl;
- *ss << "IIOP_Object *data; // Actual object reference" << nl;
- *ss << "TAO_ORB_Core *ocp = TAO_ORB_Core_instance (); " <<
- "// underlying ORB core instance" << nl;
- *ss << "CORBA::POA_ptr oa = TAO_ORB_Core_instance ()->root_poa (); " <<
- "// underlying OA" << nl;
- *ss << "const ACE_INET_Addr &addr = ocp->orb_params ()->addr ();" << nl;
- *ss << "this->optable_ = &tao_" << this->flatname () << "_optable;" << nl <<
- nl;
- *ss << "// set up an IIOP object" << nl;
- *ss << "data = new IIOP_Object (CORBA::string_dup (repoID), addr, obj_name);"
- << nl;
- *ss << "this->set_parent (data); // store the IIOP obj ref with us" <<
- nl;
- // *ss << "this->sub_ = this; // set the most derived type to be us" << nl;
- *ss << "// @@ TODO this cast is while we still have sequences " << nl
- << "// implemented using the old CORBA_SEQUENCE template " << nl;
- *ss << "if (oa) oa->bind (data->profile.object_key, this); " <<
- "// register ourselves\n";
- ss->decr_indent ();
- *ss << "}\n\n";
+ *ss << "{" << be_idt_nl
+ << "this->optable_ = &tao_" << this->flatname ()
+ << "_optable;" << be_uidt_nl
+ << "}\n\n";
// generate code for elements in the scope (e.g., operations)
if (be_scope::gen_server_skeletons () == -1)
@@ -637,44 +837,88 @@ int be_interface::gen_server_skeletons (void)
// generate code for the _is_a skeleton
ss->indent ();
- *ss << "void " << this->full_skel_name () <<
- "::_is_a_skel (CORBA::ServerRequest &req, " <<
- "void * /* obj */, void * /*context*/, CORBA::Environment &env)" << nl;
+ *ss << "void " << this->full_skel_name ()
+ << "::_is_a_skel (" << be_idt << be_idt_nl
+ << "CORBA::ServerRequest &req, " << be_nl
+ << "void * _tao_object_reference," << be_nl
+ << "void * /*context*/," << be_nl
+ << "CORBA::Environment &_tao_environment" << be_uidt_nl
+ << ")" << be_uidt_nl;
+
*ss << "{\n";
ss->incr_indent ();
*ss << "CORBA::NVList_ptr nvlist;" << nl;
*ss << "CORBA::NamedValue_ptr nv;" << nl;
*ss << "CORBA::Any temp_value (CORBA::_tc_string);" << nl;
*ss << "CORBA::Any *any;" << nl;
- *ss << "CORBA::Boolean *retval;" << nl;
+ *ss << "CORBA::Boolean *retval = new CORBA::Boolean;" << nl;
*ss << "CORBA::String value;" << nl;
*ss << nl;
*ss << "req.orb()->create_list (0, nvlist);" << nl;
- *ss << "nv = nvlist->add_value (0, temp_value, CORBA::ARG_IN, env);" << nl;
- *ss << "req.params (nvlist, env); // parse the args" << nl;
- *ss << "if (env.exception () != 0) return;" << nl;
+ *ss << "nv = nvlist->add_value (0, temp_value, "
+ << "CORBA::ARG_IN, _tao_environment);" << nl;
+ *ss << "req.params (nvlist, _tao_environment); // parse the args" << nl;
+ *ss << "if (_tao_environment.exception () != 0) return;" << nl;
*ss << "value = *(CORBA::String *)nv->value ()->value ();" << nl;
- *ss << "if (\n";
- ss->incr_indent (0);
+
+ *ss << this->full_skel_name () << "_ptr \t impl = ("
+ << this->full_skel_name () << "_ptr) _tao_object_reference;"
+ << nl;
+
+ *ss << "*retval = impl->_is_a (value, _tao_environment);" << be_nl
+ << "if (_tao_environment.exception () != 0) return;" << be_nl;
+ *ss << "any = new CORBA::Any (CORBA::_tc_boolean, "
+ << "retval, CORBA::B_TRUE);" << nl;
+ *ss << "req.result (any, _tao_environment);\n";
+ ss->decr_indent ();
+ *ss << "}\n\n";
+
+ ss->indent ();
+ *ss << "CORBA::Boolean " << this->full_skel_name ()
+ << "::_is_a (" << be_idt << be_idt_nl
+ << "const char* value," << be_nl
+ << "CORBA::Environment &_tao_environment" << be_uidt_nl
+ << ")" << be_uidt_nl
+ << "{" << be_idt_nl
+ << "if (\n" << be_idt;
if (this->traverse_inheritance_graph (be_interface::is_a_helper, ss) == -1)
{
+ return -1;
}
+
ss->indent ();
- *ss << "(!ACE_OS::strcmp ((char *)value, CORBA::_tc_Object->id (env))))\n";
- *ss << "\tretval = new CORBA::Boolean (CORBA::B_TRUE);\n";
- ss->decr_indent ();
- *ss << "else" << nl;
- *ss << "\tretval = new CORBA::Boolean (CORBA::B_FALSE);" << nl;
- *ss << "any = new CORBA::Any (CORBA::_tc_boolean, retval, CORBA::B_TRUE);" <<
- nl;
- *ss << "req.result (any, env);\n";
- ss->decr_indent ();
- *ss << "}\n\n";
+ *ss << "(!ACE_OS::strcmp ((char *)value, "
+ << "CORBA::_tc_Object->id (_tao_environment))))"
+ << be_idt_nl << "return CORBA::B_TRUE;" << be_uidt_nl
+ << "else" << be_idt_nl
+ << "return CORBA::B_FALSE;" << be_uidt << be_uidt << be_uidt_nl
+ << "}\n\n";
+
+ ss->indent ();
+ *ss << "void* " << this->full_skel_name ()
+ << "::_downcast (" << be_idt << be_idt_nl
+ << "const char* logical_type_id" << be_uidt_nl
+ << ")" << be_uidt_nl
+ << "{" << be_idt_nl;
+
+ if (this->traverse_inheritance_graph (be_interface::downcast_helper, ss) == -1)
+ {
+ return -1;
+ }
+
+ *ss << "if (ACE_OS::strcmp (logical_type_id, "
+ << "\"IDL:omg.org/CORBA/Object:1.0\") == 0)" << be_idt_nl
+ << "return ACE_static_cast(PortableServer::Servant, this);"
+ << be_uidt_nl;
+
+ *ss << "return 0;" << be_uidt_nl
+ << "}\n\n";
+
// now the dispatch method
ss->indent ();
*ss << "void " << this->full_skel_name () <<
- "::dispatch (CORBA::ServerRequest &req, " <<
+ "::_dispatch (CORBA::ServerRequest &req, " <<
"void *context, CORBA::Environment &env)" << nl;
*ss << "{\n";
ss->incr_indent ();
@@ -682,7 +926,7 @@ int be_interface::gen_server_skeletons (void)
*ss << "CORBA::String opname = req.op_name (); // retrieve operation name" <<
nl;
*ss << "// find the skeleton corresponding to this opname" << nl;
- *ss << "if (this->find (opname, skel) == -1)" << nl;
+ *ss << "if (this->_find (opname, skel) == -1)" << nl;
*ss << "{\n";
ss->incr_indent ();
*ss << "env.exception (new CORBA_BAD_OPERATION (CORBA::COMPLETED_NO));" <<
@@ -693,67 +937,69 @@ int be_interface::gen_server_skeletons (void)
*ss << "else" << nl;
*ss << "\tskel (req, this, context, env);\n";
ss->decr_indent ();
- *ss << "}\n";
- cg->pop ();
- return 0;
-}
-
-// Generates the client-side inline information
-int
-be_interface::gen_client_inline (void)
-{
- TAO_OutStream *ci; // output stream
- TAO_NL nl; // end line
-
- // retrieve a singleton instance of the code generator
- TAO_CodeGen *cg = TAO_CODEGEN::instance ();
-
- ci = cg->client_inline ();
- ci->indent (); // start from the current indentation level
-
- // generate the constructors and destructor
- *ci << "ACE_INLINE" << nl;
- *ci << this->name () << "::" << this->local_name () <<
- " (void) // default constructor" << nl;
- *ci << "{}" << nl << nl;
-
- *ci << "ACE_INLINE" << nl;
- *ci << this->name () << "::" << this->local_name () <<
- " (STUB_Object *objref) // constructor" << nl;
- *ci << "\t: CORBA_Object (objref)" << nl;
- *ci << "{}" << nl << nl;
-
- *ci << "ACE_INLINE" << nl;
- *ci << this->name () << "::~" << this->local_name () <<
- " (void) // destructor" << nl;
- *ci << "{}\n\n";
+ *ss << "}\n\n";
- // generate the ifdefined macro for the _var type
- ci->gen_ifdef_macro (this->flatname (), "_var");
+ ss->indent ();
+ *ss << "const char* " << this->full_skel_name ()
+ << "::_interface_repository_id (void) const"
+ << nl;
+ *ss << "{\n";
+ ss->incr_indent ();
+ *ss << "return \"" << this->repoID () << "\";\n";
+ ss->decr_indent ();
+ *ss << "}\n\n";
- if (this->gen_var_impl () == -1)
- {
- ACE_ERROR ((LM_ERROR, "be_interface: _var impl code gen failed\n"));
- return -1;
- }
- ci->gen_endif ();
+ cg->pop ();
- // generate the ifdefined macro for the _out type
- ci->gen_ifdef_macro (this->flatname (), "_out");
+ be_visitor_collocated_ss visitor;
+ this->accept (&visitor);
+ *ss << "\n";
+
+ *ss << this->name () << "*" << be_nl
+ << this->full_skel_name ()
+ << "::_this (CORBA_Environment &_env)" << be_nl
+ << "{" << be_idt_nl
+ << "STUB_Object *stub = this->_create_stub (_env);" << be_nl
+ << "if (_env.exception () != 0)" << be_idt_nl
+ << "return 0;" << be_uidt_nl
+
+#if 0
+ << "TAO_ORB_Core *orb_core = TAO_ORB_Core_instance ();" << be_nl
+ << "if (orb_core->get_current ()->in_servant_upcall ())" << be_nl
+ << "{" << be_idt << be_nl
+ << "stub = new IIOP_Object (" << be_idt << be_idt << be_nl
+ << "CORBA::string_copy (this->_interface_repository_id ())," << be_nl
+ << "IIOP::Profile (" << be_idt << be_idt << be_nl
+ << "TAO_ORB_Core_instance ()->orb_params ()->addr ()," << be_nl
+ << "orb_core->get_current ()->object_key ()" << be_uidt << be_nl
+ << ")" << be_uidt << be_uidt << be_nl
+ << ");" << be_uidt << be_uidt << be_nl
+ << "}" << be_nl
+ << "else" << be_nl
+ << "{" << be_idt_nl
+ << "POA* poa = this->default_poa (_env);" << be_nl
+ << "if (_env.exception () != 0)" << be_idt << be_nl
+ << "return 0;" << be_uidt << be_nl
+ << "const TAO::ObjectKey& object_key = " << be_idt << be_nl
+ << "poa->servant_to_id (this, _env);" << be_uidt << be_nl
+ << "if (_env.exception () != 0)" << be_idt << be_nl
+ << "return 0;" << be_uidt << be_nl
+ << "stub = new IIOP_Object (" << be_idt << be_idt << be_nl
+ << "CORBA::string_copy (this->_interface_repository_id ())," << be_nl
+ << "IIOP::Profile (" << be_idt << be_idt << be_nl
+ << "TAO_ORB_Core_instance ()->orb_params ()->addr ()," << be_nl
+ << "object_key" << be_uidt << be_nl
+ << ")" << be_uidt << be_uidt << be_nl
+ << ");" << be_uidt << be_uidt << be_nl
+ << "}\n" << be_nl
+#endif /* 0 */
+
+ << "return new " << this->full_coll_name ()
+ << " (this, stub);" << be_uidt << be_nl;
- if (this->gen_out_impl () == -1)
- {
- ACE_ERROR ((LM_ERROR, "be_interface: _out impl code gen failed\n"));
- return -1;
- }
- ci->gen_endif ();
+ *ss << "}\n\n";
- if (be_scope::gen_client_inline () == -1)
- {
- ACE_ERROR ((LM_ERROR, "be_interface: code gen failed for scope\n"));
- return -1;
- }
- return 0;
+ return 0;
}
// Generates the server-side inline
@@ -793,9 +1039,10 @@ be_interface::gen_server_inline (void)
" (void)" << nl;
}
- *si << "{" << nl;
+ *si << "{\n";
*si << "}\n";
+
// generate skeletons for operations of our base classes. These skeletons
// just cast the pointer to the appropriate type before invoking the call
if (this->traverse_inheritance_graph (be_interface::gen_skel_helper, si) == -1)
@@ -1612,7 +1859,9 @@ be_interface::gen_optable_helper (be_interface *derived,
}
int
-be_interface::is_a_helper (be_interface * /*derived*/, be_interface *bi, TAO_OutStream *os)
+be_interface::is_a_helper (be_interface * /*derived*/,
+ be_interface *bi,
+ TAO_OutStream *os)
{
// emit the comparison code
os->indent ();
@@ -1623,6 +1872,18 @@ be_interface::is_a_helper (be_interface * /*derived*/, be_interface *bi, TAO_Out
}
int
+be_interface::downcast_helper (be_interface * /* derived */,
+ be_interface *base,
+ TAO_OutStream *os)
+{
+ *os << "if (ACE_OS::strcmp (logical_type_id, \""
+ << base->repoID () << "\") == 0)" << be_idt_nl
+ << "return ACE_static_cast ("
+ << base->full_skel_name () << "_ptr, this);" << be_uidt_nl;
+ return 0;
+}
+
+int
be_interface::gen_skel_helper (be_interface *derived,
be_interface *ancestor,
TAO_OutStream *os)
@@ -1753,14 +2014,29 @@ be_interface::gen_skel_helper (be_interface *derived,
return 0;
}
+const char*
+be_interface::relative_coll_name (const char *collname)
+{
+ return be_interface::relative_name (this->full_coll_name (),
+ collname);
+}
+
// return the relative skeleton name (needed due to NT compiler insanity)
-char *
+const char *
be_interface::relative_skel_name (const char *skelname)
{
- // some compilers do not like generating a fully scoped name for a type that
- // was defined in the same enclosing scope in which it was defined. For such,
- // we emit a macro defined in the ACE library.
- //
+ return be_interface::relative_name (this->full_skel_name (),
+ skelname);
+}
+
+const char*
+be_interface::relative_name (const char *localname,
+ const char *othername)
+{
+ // some compilers do not like generating a fully scoped name for a
+ // type that was defined in the same enclosing scope in which it was
+ // defined. We have to emit just the partial name, relative to our
+ // "localname"
// The tricky part here is that it is not enough to check if the
// typename we are using was defined in the current scope. But we
@@ -1792,8 +2068,8 @@ be_interface::relative_skel_name (const char *skelname)
// macro. Whenever there is no match, the remaining components of the
// def_scope form the second argument
- ACE_OS::strcpy (def_name, this->full_skel_name ());
- ACE_OS::strcpy (use_name, skelname);
+ ACE_OS::strcpy (def_name, localname);
+ ACE_OS::strcpy (use_name, othername);
while (def_curr && use_curr)
{
@@ -1845,6 +2121,13 @@ be_interface::accept (be_visitor *visitor)
return visitor->visit_interface (this);
}
+int be_interface::write_as_return (TAO_OutStream *stream,
+ be_type *type)
+{
+ *stream << type->name () << "_ptr";
+ return 0;
+}
+
// Narrowing
IMPL_NARROW_METHODS3 (be_interface, AST_Interface, be_scope, be_type)
IMPL_NARROW_FROM_DECL (be_interface)