summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorgokhale <asgokhale@users.noreply.github.com>1997-12-02 22:42:14 +0000
committergokhale <asgokhale@users.noreply.github.com>1997-12-02 22:42:14 +0000
commit7e2cddd99343d142b3d73fddab71df97e0c61521 (patch)
tree52da46fce18e16c40a8139f76708bec3273a0a9e
parent45ba7ed240b1ddaf7fbad6ddee569b4165300d57 (diff)
downloadATCD-7e2cddd99343d142b3d73fddab71df97e0c61521.tar.gz
code for inherited interfaces
CVS: CVS: CVS: CVS:
-rw-r--r--TAO/TAO_IDL/be/be_attribute.cpp23
-rw-r--r--TAO/TAO_IDL/be/be_exception.cpp32
-rw-r--r--TAO/TAO_IDL/be/be_interface.cpp584
-rw-r--r--TAO/TAO_IDL/be/be_operation.cpp17
-rw-r--r--TAO/TAO_IDL/be/be_string.cpp1
-rw-r--r--TAO/TAO_IDL/be_include/be.h7
-rw-r--r--TAO/TAO_IDL/be_include/be_interface.h30
7 files changed, 543 insertions, 151 deletions
diff --git a/TAO/TAO_IDL/be/be_attribute.cpp b/TAO/TAO_IDL/be/be_attribute.cpp
index fa87112369b..f3f0e89ce48 100644
--- a/TAO/TAO_IDL/be/be_attribute.cpp
+++ b/TAO/TAO_IDL/be/be_attribute.cpp
@@ -417,8 +417,8 @@ be_attribute::gen_server_header (void)
// generate the static method corresponding to the method
*sh << "static void _get_" << this->local_name () <<
- "_skel (CORBA::ServerRequest &req, " <<
- "CORBA::Object_ptr obj, CORBA::Environment &env);\n\n";
+ "_skel (CORBA::ServerRequest &req, void *obj, " <<
+ "void *context, CORBA::Environment &env);\n\n";
// now the set method. However, this is not defined if we are readonly
@@ -445,8 +445,8 @@ be_attribute::gen_server_header (void)
// generate the static method corresponding to the method
*sh << "static void _set_" << this->local_name () <<
- "_skel (CORBA::ServerRequest &req, " <<
- "CORBA::Object_ptr obj, CORBA::Environment &env);\n\n";
+ "_skel (CORBA::ServerRequest &req, void *obj, " <<
+ "void *context, CORBA::Environment &env);\n\n";
return 0;
@@ -492,12 +492,13 @@ be_attribute::gen_server_skeletons (void)
*ss << "void " << intf->full_skel_name () << "::_get_"
<< this->local_name () << "_skel ("
<< "CORBA::ServerRequest &_tao_server_request, "
- << "CORBA::Object_ptr _tao_object_reference, "
+ << "void *_tao_object_reference, void */*context*/, "
<< "CORBA::Environment &_tao_environment)" << nl;
*ss << "{\n";
ss->incr_indent ();
// define a variable that will eventually point to our implementation object
- *ss << intf->full_skel_name () << "_ptr \t impl;" << nl;
+ *ss << intf->full_skel_name () << "_ptr impl = (" << intf->full_skel_name ()
+ << "_ptr) _tao_object_reference;" << nl;
// store the result in this Any
*ss << "CORBA::Any *result;" << nl;
// emit the return type
@@ -518,8 +519,6 @@ be_attribute::gen_server_skeletons (void)
*ss << "// this method has no incoming parameters. Nothing to parse" << nl;
// make the upcall
- *ss << "impl = (" << intf->full_skel_name () << "_ptr) _tao_object_reference->get_subclass ();"
- << nl;
cg->push (TAO_CodeGen::TAO_ATTRIBUTE_RETVAL_ASSIGN_SS);
s = cg->make_state ();
// emit code to assign to retval
@@ -558,14 +557,15 @@ be_attribute::gen_server_skeletons (void)
*ss << "void " << intf->full_skel_name () << "::_set_"
<< this->local_name () << "_skel ("
<< "CORBA::ServerRequest &_tao_server_request, "
- << "CORBA::Object_ptr _tao_object_reference, "
+ << "void *_tao_object_reference, void */*context*/, "
<< "CORBA::Environment &_tao_environment)" << nl;
*ss << "{\n";
ss->incr_indent ();
// define an NVList to hold the in argument
*ss << "CORBA::NVList_ptr \t nvlist;" << nl;
// define a variable that will eventually point to our implementation object
- *ss << intf->full_skel_name () << "_ptr \t impl;" << nl;
+ *ss << intf->full_skel_name () << "_ptr \t impl = (" << intf->full_skel_name
+ () << "_ptr)_tao_object_reference;" << nl;
// if we have any arguments, get each one of them and allocate an Any and
// NamedValue for each. In addition, define a variable of that type
@@ -607,9 +607,6 @@ be_attribute::gen_server_skeletons (void)
cg->pop ();
// make the upcall
- *ss << "impl = (" << intf->full_skel_name () << "_ptr) _tao_object_reference->get_subclass ();"
- << nl;
-
*ss << "impl->" << this->local_name () << "(";
cg->push (TAO_CodeGen::TAO_ATTRIBUTE_UPCALL_SS);
s = cg->make_state ();
diff --git a/TAO/TAO_IDL/be/be_exception.cpp b/TAO/TAO_IDL/be/be_exception.cpp
index b06f60afe3b..8ce0580afc1 100644
--- a/TAO/TAO_IDL/be/be_exception.cpp
+++ b/TAO/TAO_IDL/be/be_exception.cpp
@@ -1,6 +1,25 @@
//
// $Id$
//
+// ============================================================================
+//
+// = LIBRARY
+// TAO IDL
+//
+// = FILENAME
+// be_exception.cpp
+//
+// = DESCRIPTION
+// Extension of class AST_Exception that provides additional means for C++
+// mapping of an interface.
+//
+// = AUTHOR
+// Copyright 1994-1995 by Sun Microsystems, Inc.
+// and
+// Aniruddha Gokhale
+//
+// ============================================================================
+
#include "idl.h"
#include "idl_extern.h"
@@ -26,7 +45,6 @@ int
be_exception::compute_member_count (void)
{
UTL_ScopeActiveIterator *si; // iterator
- AST_Decl *d; // temp node
this->member_count_ = 0;
@@ -37,13 +55,9 @@ be_exception::compute_member_count (void)
si = new UTL_ScopeActiveIterator (this, UTL_Scope::IK_decls);
while (!(si->is_done ()))
- {
- // get the next AST decl node
- d = si->item ();
- if (!d->imported ())
- {
- this->member_count_++;
- }
+ {
+ // get the next AST decl node
+ this->member_count_++;
si->next ();
} // end of while
delete si; // free the iterator object
@@ -218,7 +232,7 @@ be_exception::gen_typecode (void)
cs = cg->client_stubs ();
cs->indent (); // start from whatever indentation level we were at
- *cs << "CORBA::tk_struct, // typecode kind" << nl;
+ *cs << "CORBA::tk_except, // typecode kind" << nl;
*cs << this->tc_size () << ", // encapsulation length\n";
// now emit the encapsulation
return this->gen_encapsulation ();
diff --git a/TAO/TAO_IDL/be/be_interface.cpp b/TAO/TAO_IDL/be/be_interface.cpp
index 8b730d4dff9..e5c5f6cf516 100644
--- a/TAO/TAO_IDL/be/be_interface.cpp
+++ b/TAO/TAO_IDL/be/be_interface.cpp
@@ -27,7 +27,8 @@
// default constructor
be_interface::be_interface (void)
- : full_skel_name_ (0)
+ : full_skel_name_ (0),
+ skel_count_ (0)
{
this->size_type (be_decl::VARIABLE); // always the case
}
@@ -38,7 +39,8 @@ be_interface::be_interface (UTL_ScopedName *n, AST_Interface **ih, long nih,
: AST_Interface (n, ih, nih, p),
AST_Decl (AST_Decl::NT_interface, n, p),
UTL_Scope (AST_Decl::NT_interface),
- full_skel_name_ (0)
+ full_skel_name_ (0),
+ skel_count_ (0)
{
this->size_type (be_decl::VARIABLE); // always the case
}
@@ -109,6 +111,7 @@ be_interface::compute_fullskelname (void)
return;
}
+// retrieve the fully scoped skeleton name
const char*
be_interface::full_skel_name (void)
{
@@ -217,6 +220,11 @@ int be_interface::gen_client_header (void)
return -1;
}
+ // the _is_a method
+ ch->indent ();
+ *ch << "virtual CORBA::Boolean _is_a (const CORBA::Char *type_id, " <<
+ "CORBA::Environment &env);\n";
+
// generate the "protected" constructor so that users cannot instantiate
// us
ch->decr_indent ();
@@ -399,6 +407,29 @@ int be_interface::gen_client_stubs (void)
return -1;
}
+ // generate the is_a method
+ cs->indent ();
+ *cs << "CORBA::Boolean " << this->name () << "::_is_a (" <<
+ "const CORBA::Char *value, CORBA::Environment &env)" << nl;
+ *cs << "{\n";
+ cs->incr_indent ();
+ *cs << "if (\n";
+ cs->incr_indent (0);
+ if (this->traverse_inheritance_graph (be_interface::is_a_helper, cs) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_interface::gen_client_stubs - "
+ "inheritance graph failed\n"), -1);
+ }
+ cs->indent ();
+ *cs << "(!ACE_OS::strcmp ((char *)value, CORBA::_tc_Object->id (env))))\n";
+ *cs << "\treturn 1; // success using local knowledge\n";
+ cs->decr_indent ();
+ *cs << "else" << nl;
+ *cs << "\treturn CORBA::Object::_is_a (value, env); // remote call\n";
+ cs->decr_indent ();
+ *cs << "}\n\n";
+
// generate the typecode information here
cs->indent (); // start from current indentation level
*cs << "static const CORBA::Long _oc_" << this->flatname () << "[] =" <<
@@ -501,8 +532,21 @@ int be_interface::gen_server_header (void)
// add our _is_a method
sh->indent ();
*sh << "static void _is_a_skel (CORBA::ServerRequest &req, " <<
- "CORBA::Object_ptr obj, CORBA::Environment &env);\n\n";
+ "void *obj, void *context, CORBA::Environment &env);\n\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, sh) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_interface::gen_server_header - "
+ "inheritance graph traversal failed\n"), -1);
+ }
+ // add the dispatch method
+ sh->indent ();
+ *sh << "virtual void dispatch (CORBA::ServerRequest &req, " <<
+ "void *context, CORBA::Environment &env);" << nl;
sh->decr_indent ();
*sh << "};\n\n";
@@ -513,13 +557,9 @@ int be_interface::gen_server_header (void)
int be_interface::gen_server_skeletons (void)
{
TAO_OutStream *ss; // output stream
- long i; // loop index
TAO_NL nl; // end line
AST_Decl *d; // temporary
- // 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 ();
cg->push (TAO_CodeGen::TAO_INTERFACE_SS); // set the current code generation
@@ -545,7 +585,8 @@ int be_interface::gen_server_skeletons (void)
// find if we are at the top scope or inside some module
d = ScopeAsDecl (this->defined_in ());
- if (d && d->node_type () == AST_Decl::NT_root)
+ // if (d && d->node_type () == AST_Decl::NT_root)
+ if (!this->is_nested ())
{
// we are outermost. So the POA_ prefix is prepended to our name
*ss << this->full_skel_name () << "::POA_" << this->local_name () <<
@@ -571,28 +612,11 @@ int be_interface::gen_server_skeletons (void)
*ss << "this->optable_ = &tao_" << this->flatname () << "_optable;" << nl <<
nl;
*ss << "// set up an IIOP object" << nl;
-#if 0
- *ss << "data = new IIOP_Object (CORBA::string_dup (repoID));" << nl;
- *ss << "data->profile.iiop_version.major = IIOP::MY_MAJOR;" << nl;
- *ss << "data->profile.iiop_version.minor = IIOP::MY_MINOR;" << nl;
- *ss << "const ACE_INET_Addr &addr = ocp->orb_params ()->addr ();" << nl;
- *ss << "data->profile.host = ACE_OS::strdup (" <<
- "addr.get_host_name ());" << nl;
- *ss << "data->profile.port = addr.get_port_number ();" << nl;
- *ss << "data->profile.object_key.length = " <<
- "ACE_OS::strlen (obj_name);" << nl;
- *ss << "data->profile.object_key.maximum = " <<
- "data->profile.object_key.length;" << nl;
- *ss << "data->profile.object_key.buffer = " <<
- "new CORBA::Octet [(size_t)data->profile.object_key.length+1];" << nl;
- *ss << "ACE_OS::strcpy ((char *)data->profile.object_key.buffer, obj_name);"
- << " // set the object key" << nl;
-#endif
*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 << "this->sub_ = this; // set the most derived type to be us" << nl;
*ss << "if (oa) oa->bind (data->profile.object_key, this); " <<
"// register ourselves\n";
ss->decr_indent ();
@@ -610,7 +634,7 @@ int be_interface::gen_server_skeletons (void)
ss->indent ();
*ss << "void " << this->full_skel_name () <<
"::_is_a_skel (CORBA::ServerRequest &req, " <<
- "CORBA::Object_ptr /* obj */, CORBA::Environment &env)" << nl;
+ "void * /* obj */, void * /*context*/, CORBA::Environment &env)" << nl;
*ss << "{\n";
ss->incr_indent ();
*ss << "const CORBA::String type_id = \"" << this->repoID () <<
@@ -627,11 +651,16 @@ int be_interface::gen_server_skeletons (void)
*ss << "req.params (nvlist, env); // parse the args" << nl;
*ss << "if (env.exception () != 0) return;" << nl;
*ss << "value = *(CORBA::String *)nv->value ()->value ();" << nl;
- *ss << "if (ACE_OS::strcmp ((char *)value, (char *)type_id) == 0" << nl;
- *ss << " || ACE_OS::strcmp ((char *)value, CORBA::_tc_Object->id (env)) == 0)\n"
- << nl;
- *ss << "\tretval = new CORBA::Boolean (CORBA::B_TRUE);" << nl;
- * ss << "else" << nl;
+ *ss << "if (\n";
+ ss->incr_indent (0);
+ if (this->traverse_inheritance_graph (be_interface::is_a_helper, ss) == -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;
@@ -639,94 +668,30 @@ int be_interface::gen_server_skeletons (void)
ss->decr_indent ();
*ss << "}\n\n";
- cg->pop ();
- return 0;
-}
-
-// helper
-int
-be_interface::gen_operation_table (void)
-{
- int count = 0;
- UTL_ScopeActiveIterator *si;
- AST_Decl *d;
- TAO_OutStream *ss; // 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 ();
-
- ss = cg->server_skeletons ();
-
- ss->indent (); // start from current indentation level
- *ss << "static const TAO_operation_db_entry " << this->flatname () <<
- "_operations [] = {\n";
+ // now the dispatch method
+ ss->indent ();
+ *ss << "void " << this->full_skel_name () <<
+ "::dispatch (CORBA::ServerRequest &req, " <<
+ "void *context, CORBA::Environment &env)" << nl;
+ *ss << "{\n";
ss->incr_indent ();
- if (this->nmembers () > 0)
- {
- // if there are elements in this scope
-
- si = new UTL_ScopeActiveIterator (this, UTL_Scope::IK_decls);
- // instantiate a scope iterator.
-
- while (!(si->is_done ()))
- {
- // get the next AST decl node
- d = si->item ();
- if (!d->imported ())
- {
- // we are not imported.
-
- if (d->node_type () == AST_Decl::NT_op)
- {
- // we are an operation node
- *ss << "{\"" << d->local_name () << "\", &" << this->full_skel_name
- () << "::" << d->local_name () << "_skel},"
- << nl;
- count++;
- }
- else if (d->node_type () == AST_Decl::NT_attr)
- {
- AST_Attribute *attr;
-
- // generate only the "get" entry if we are readonly
- *ss << "{\"_get_" << d->local_name () << "\", &" <<
- this->full_skel_name () << "::_get_" << d->local_name () <<
- "_skel}," << nl;
- count++;
-
- attr = AST_Attribute::narrow_from_decl (d);
- if (!attr)
- return -1;
-
- if (!attr->readonly ())
- {
- // the set method
- *ss << "{\"_set_" << d->local_name () << "\", &" <<
- this->full_skel_name () << "::_set_" << d->local_name
- () << "_skel}," << nl;
- count++;
- }
- }
- }
- si->next ();
- } // end of while
- delete si; // free the iterator object
- }
- *ss << "{\"_is_a\", &" << this->full_skel_name () << "::_is_a_skel}\n";
- count++;
+ *ss << "TAO_Skeleton skel; // pointer to skeleton for operation" << nl;
+ *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 << "{\n";
+ ss->incr_indent ();
+ *ss << "env.exception (new CORBA_BAD_OPERATION (CORBA::COMPLETED_NO));" <<
+ nl;
+ *ss << "ACE_ERROR ((LM_ERROR, \"Bad operation <%s>\\n\", opname));\n";
ss->decr_indent ();
- *ss << "};" << nl << nl;
-
- // XXXASG - this code should be based on using different strategies for
- // demux - for next release
- *ss << "TAO_Dynamic_Hash_OpTable tao_" << this->flatname () << "_optable " <<
- "(" << this->flatname () << "_operations, " << count << ", " << 2*count << ");"
- << nl;
+ *ss << "}\n";
+ *ss << "else" << nl;
+ *ss << "\tskel (req, this, context, env);\n";
+ ss->decr_indent ();
+ *ss << "}\n";
+ cg->pop ();
return 0;
}
@@ -828,6 +793,15 @@ be_interface::gen_server_inline (void)
*si << "{" << nl;
*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)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_interface::gen_server_inline - "
+ "inheritance graph traversal failed\n"), -1);
+ }
+
return 0;
}
@@ -1373,7 +1347,381 @@ be_interface::tc_encap_len (void)
return this->encap_len_;
}
+// helper
+int
+be_interface::gen_operation_table (void)
+{
+ TAO_OutStream *ss; // output stream
+ TAO_NL nl; // end line
+
+ // retrieve a singleton instance of the code generator
+ TAO_CodeGen *cg = TAO_CODEGEN::instance ();
+
+ ss = cg->server_skeletons ();
+
+ ss->indent (); // start from current indentation level
+ *ss << "static const TAO_operation_db_entry " << this->flatname () <<
+ "_operations [] = {\n";
+ ss->incr_indent (0);
+
+ if (this->traverse_inheritance_graph (be_interface::gen_optable_helper, ss) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_interface::gen_operation_table - "
+ "inheritance graph traversal failed\n"), -1);
+ }
+
+ // generate the skeleton for the is_a method
+ ss->indent ();
+ *ss << "{\"_is_a\", &" << this->full_skel_name () << "::_is_a_skel}\n";
+ this->skel_count_++;
+
+ ss->decr_indent ();
+ *ss << "};" << nl << nl;
+
+ // XXXASG - this code should be based on using different strategies for
+ // demux - for next release
+ *ss << "TAO_Dynamic_Hash_OpTable tao_" << this->flatname () << "_optable " <<
+ "(" << this->flatname () << "_operations, " << this->skel_count_ << ", " <<
+ 2*this->skel_count_ << ");"
+ << nl;
+ return 0;
+}
+
+// we separate the generation of operation table entries from the
+// "gen_operation_table" method. This enables us to invoke generation of
+// entries for interfaces from which we inherit without any additional
+// code. The parameter "derived" is the one for which the entire operation
+// table is being built.
+int
+be_interface::gen_optable_entries (be_interface *derived)
+{
+ UTL_ScopeActiveIterator *si;
+ AST_Decl *d;
+ TAO_OutStream *ss; // output stream
+
+ // retrieve a singleton instance of the code generator
+ TAO_CodeGen *cg = TAO_CODEGEN::instance ();
+
+ ss = cg->server_skeletons ();
+
+ if (this->nmembers () > 0)
+ {
+ // if there are elements in this scope i.e., any operations and
+ // attributes defined by "this" which happens to be the same as "derived"
+ // or one of its ancestors.
+
+ si = new UTL_ScopeActiveIterator (this, UTL_Scope::IK_decls);
+ // instantiate a scope iterator.
+
+ while (!(si->is_done ()))
+ {
+ // get the next AST decl node
+ d = si->item ();
+ if (d->node_type () == AST_Decl::NT_op)
+ {
+ ss->indent (); // start from current indentation level
+ // we are an operation node
+ *ss << "{\"" << d->local_name () << "\", &" << derived->full_skel_name
+ () << "::" << d->local_name () << "_skel},\n";
+ derived->skel_count_++;
+ }
+ else if (d->node_type () == AST_Decl::NT_attr)
+ {
+ AST_Attribute *attr;
+
+ ss->indent (); // start from current indentation level
+ // generate only the "get" entry if we are readonly
+ *ss << "{\"_get_" << d->local_name () << "\", &" <<
+ derived->full_skel_name () << "::_get_" << d->local_name () <<
+ "_skel},\n";
+ derived->skel_count_++;
+
+ attr = AST_Attribute::narrow_from_decl (d);
+ if (!attr)
+ return -1;
+
+ if (!attr->readonly ())
+ {
+ // the set method
+ ss->indent (); // start from current indentation level
+ *ss << "{\"_set_" << d->local_name () << "\", &" <<
+ derived->full_skel_name () << "::_set_" << d->local_name
+ () << "_skel},\n";
+ derived->skel_count_++;
+ }
+ }
+ si->next ();
+ } // end of while
+ delete si; // free the iterator object
+ }
+ return 0;
+}
+
+// template method that traverses the inheritance graph in a breadth-first
+// style. The actual work on each element in the inheritance graph is carried
+// out by the function passed as argument
+int be_interface::traverse_inheritance_graph (be_interface::tao_code_emitter gen,
+ TAO_OutStream *os)
+{
+ long i; // loop index
+ ACE_Unbounded_Queue <be_interface*> queue; // Queue data structure needed for
+ // breadth-first traversal of
+ // inheritance tree
+ // insert ourselves in the Queue
+ if (queue.enqueue_tail (this) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR, "(%N:%l) be_interface::gen_operation_table - "
+ "error generating entries\n"), -1);
+ }
+
+ // do until queue is empty
+ while (!queue.is_empty ())
+ {
+ be_interface *bi; // element inside the queue
+
+ // use breadth-first strategy i.e., first generate entries for ourselves,
+ // followed by nodes that we immediately inherit from, and so on. In the
+ // process make sure that we do not generate code for the same node more
+ // than once. Such a case may arise due to multiple inheritance forming a
+ // diamond like inheritance graph.
+
+ // dequeue the element at the head of the queue
+ if (queue.dequeue_head (bi))
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_interface::traverse_graph - "
+ "dequeue_head failed\n"), -1);
+ }
+
+ // use the helper method to generate code for ourself using the
+ // properties of the element dequeued. For the first iteration, the
+ // element dequeued and "this" will be the same i.e., ourselves
+ if (gen (this, bi, os) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_interface::traverse_graph - "
+ "helper code gen failed\n"), -1);
+ }
+
+ // now check if the dequeued element has any ancestors. If yes, insert
+ // them inside the queue making sure that there are no duplicates
+ for (i=0; i < bi->n_inherits (); i++)
+ {
+ be_interface *parent; // parent of the dequeued element
+
+ // initialize an iterator to search the queue for duplicates
+ ACE_Unbounded_Queue_Iterator<be_interface*> q_iter (queue);
+
+ // retrieve the next parent from which the dequeued element inherits
+ parent = be_interface::narrow_from_decl (bi->inherits ()[i]);
+ if (!parent)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_interface::gen_server_skeletons - "
+ "bad inherited interface\n"), -1);
+ }
+
+ // now insert this node at the tail of the queue, but make sure that
+ // it doesn't already exist in the queue
+ int found = 0;
+ while (!q_iter.done ())
+ {
+ be_interface **temp; // queue element
+
+ (void) q_iter.next (temp);
+ if (!ACE_OS::strcmp (parent->fullname (), (*temp)->fullname ()))
+ {
+ // we exist in this queue and cannot be inserted
+ found = 1;
+ }
+ if (found)
+ break;
+ (void) q_iter.advance ();
+ } // end of while
+ if (!found)
+ {
+ // insert the parent in the queue
+ if (queue.enqueue_tail (parent) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_interface::gen_server_skeletons - "
+ "enqueue op failed\n"), -1);
+ }
+ }
+ } // end of for loop
+ } // end of while queue not empty
+ return 0;
+}
+
+// helpers passed to the template method
+
+int
+be_interface::gen_optable_helper (be_interface *derived,
+ be_interface *ancestor,
+ TAO_OutStream */*os*/)
+{
+ // generate entries for the derived class using the properties of its
+ // ancestors
+ if (ancestor->gen_optable_entries (derived) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_interface::gen_operation_table - "
+ "error generating entries for inherited"
+ "interfaces\n"), -1);
+ }
+ return 0;
+}
+
+int
+be_interface::is_a_helper (be_interface */*derived*/, be_interface *bi, TAO_OutStream *os)
+{
+ // emit the comparison code
+ os->indent ();
+ *os << "(!ACE_OS::strcmp ((char *)value, \"" << bi->repoID () <<
+ "\")) ||\n";
+
+ return 0;
+}
+
+int
+be_interface::gen_skel_helper (be_interface *derived,
+ be_interface *ancestor,
+ TAO_OutStream *os)
+{
+ UTL_ScopeActiveIterator *si;
+ AST_Decl *d;
+ TAO_NL nl; // end line
+
+ // if derived and ancestor are same, skip it
+ if (derived == ancestor)
+ return 0;
+
+ // else generate code that does the cast to the appropriate type
+
+ if (ancestor->nmembers () > 0)
+ {
+ // if there are elements in ancestor scope i.e., any operations and
+ // attributes defined by "ancestor", become methods on the derived class
+ // which call the corresponding method of the base class by doing the
+ // proper casting
+
+ si = new UTL_ScopeActiveIterator (ancestor, UTL_Scope::IK_decls);
+ // instantiate a scope iterator.
+
+ while (!(si->is_done ()))
+ {
+ // get the next AST decl node
+ d = si->item ();
+ if (d->node_type () == AST_Decl::NT_op)
+ {
+ os->indent (); // start from current indentation level
+ if (os->stream_type () == TAO_OutStream::TAO_SVR_HDR)
+ {
+ // generate the static method corresponding to this method
+ *os << "static void " << d->local_name () <<
+ "_skel (CORBA::ServerRequest &req, void *obj,"
+ << " void *context, CORBA::Environment &env);\n\n";
+ }
+ else
+ { // generate code in the inline file
+ // generate the static method corresponding to this method
+ *os << "ACE_INLINE void " << derived->full_skel_name () <<
+ "::" << d->local_name () <<
+ "_skel (CORBA::ServerRequest &req, " <<
+ "void *obj, void *context, CORBA::Environment &env)" << nl;
+ *os << "{\n";
+ os->incr_indent ();
+ *os << ancestor->full_skel_name () << "_ptr impl = (" <<
+ derived->full_skel_name () << "_ptr) obj;" << nl;
+ *os << ancestor->full_skel_name () << "::" << d->local_name
+ () << "_skel (req, impl, context, env);\n";
+ os->decr_indent ();
+ *os << "}\n";
+ }
+ }
+ else if (d->node_type () == AST_Decl::NT_attr)
+ {
+ AST_Attribute *attr;
+
+ attr = AST_Attribute::narrow_from_decl (d);
+ if (!attr)
+ return -1;
+
+ os->indent (); // start from current indentation level
+ if (os->stream_type () == TAO_OutStream::TAO_SVR_HDR)
+ {
+ // generate the static method corresponding to this method
+ *os << "static void _get_" << d->local_name () <<
+ "_skel (CORBA::ServerRequest &req, void *obj,"
+ << " void *context, CORBA::Environment &env);\n\n";
+ }
+ else
+ { // generate code in the inline file
+ // generate the static method corresponding to this method
+ *os << "ACE_INLINE void " << derived->full_skel_name () <<
+ "::_get_" << d->local_name () <<
+ "_skel (CORBA::ServerRequest &req, " <<
+ "void *obj, void *context, CORBA::Environment &env)" << nl;
+ *os << "{\n";
+ os->incr_indent ();
+ *os << ancestor->full_skel_name () << "_ptr impl = (" <<
+ derived->full_skel_name () << "_ptr) obj;" << nl;
+ *os << ancestor->full_skel_name () << "::_get_" << d->local_name
+ () << "_skel (req, impl, context, env);\n";
+ os->decr_indent ();
+ *os << "}\n";
+ }
+
+ if (!attr->readonly ())
+ {
+ // the set method
+ os->indent (); // start from current indentation level
+ if (os->stream_type () == TAO_OutStream::TAO_SVR_HDR)
+ {
+ // generate the static method corresponding to this method
+ *os << "static void _set_" << d->local_name () <<
+ "_skel (CORBA::ServerRequest &req, void *obj,"
+ << " void *context, CORBA::Environment &env);\n\n";
+ }
+ else
+ { // generate code in the inline file
+ // generate the static method corresponding to this method
+ *os << "ACE_INLINE void " << derived->full_skel_name ()
+ << "::_set_" << d->local_name () <<
+ "_skel (CORBA::ServerRequest &req, " <<
+ "void *obj, void *context, CORBA::Environment &env)" <<
+ nl;
+ *os << "{\n";
+ os->incr_indent ();
+ *os << ancestor->full_skel_name () << "_ptr impl = (" <<
+ derived->full_skel_name () << "_ptr) obj;" << nl;
+ *os << ancestor->full_skel_name () << "::_get_" <<
+ d->local_name () << "_skel (req, impl, context, env);\n";
+ os->decr_indent ();
+ *os << "}\n";
+ }
+
+ }
+ }
+ si->next ();
+ } // end of while
+ delete si; // free the iterator object
+ }
+ return 0;
+}
+
// Narrowing
IMPL_NARROW_METHODS3 (be_interface, AST_Interface, be_scope, be_type)
IMPL_NARROW_FROM_DECL (be_interface)
IMPL_NARROW_FROM_SCOPE (be_interface)
+
+#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION)
+template class ACE_Node <be_interface*>;
+template class ACE_Unbounded_Queue <be_interface*>;
+template class ACE_Unbounded_Queue_Iterator <be_interface*>;
+#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA)
+#pragma instantiate ACE_Node<be_interface*>
+#pragma instantiate ACE_Unbounded_Queue<be_interface*>
+#pragma instantiate ACE_Unbounded_Queue_Iterator<be_interface*>
+#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */
diff --git a/TAO/TAO_IDL/be/be_operation.cpp b/TAO/TAO_IDL/be/be_operation.cpp
index 07fae5799dd..c669fb6952f 100644
--- a/TAO/TAO_IDL/be/be_operation.cpp
+++ b/TAO/TAO_IDL/be/be_operation.cpp
@@ -408,8 +408,9 @@ be_operation::gen_server_header (void)
sh->indent ();
// generate the static method corresponding to this method
- *sh << "static void " << this->local_name () << "_skel (CORBA::ServerRequest &req,"
- << " CORBA::Object_ptr obj, CORBA::Environment &env);\n\n";
+ *sh << "static void " << this->local_name () <<
+ "_skel (CORBA::ServerRequest &req, void *obj,"
+ << " void *context, CORBA::Environment &env);\n\n";
cg->pop (); // restore previous state
return 0;
}
@@ -446,14 +447,18 @@ be_operation::gen_server_skeletons (void)
*ss << "void " << intf->full_skel_name () << "::"
<< this->local_name () << "_skel ("
<< "CORBA::ServerRequest &_tao_server_request, "
- << "CORBA::Object_ptr _tao_object_reference, "
+ //@@XXASG << "CORBA::Object_ptr _tao_object_reference, "
+ << "void *_tao_object_reference, "
+ << "void *context, "
<< "CORBA::Environment &_tao_environment)" << nl;
*ss << "{\n";
ss->incr_indent ();
+ *ss << "ACE_UNUSED_ARG (context);" << nl;
// define an NVList to hold arguments
*ss << "CORBA::NVList_ptr \t nvlist;" << nl;
// define a variable that will eventually point to our implementation object
- *ss << intf->full_skel_name () << "_ptr \t impl;" << nl;
+ *ss << intf->full_skel_name () << "_ptr \t impl = (" << intf->full_skel_name
+ () << "_ptr) _tao_object_reference;" << nl;
// verify if we need to define a variable intended to hold the operation
// return type. We do not need one if the return type is void
@@ -564,8 +569,8 @@ be_operation::gen_server_skeletons (void)
cg->pop ();
// make the upcall
- *ss << "impl = (" << intf->full_skel_name () << "_ptr) _tao_object_reference->get_subclass ();"
- << nl;
+ // *ss << "impl = (" << intf->full_skel_name () << "_ptr) _tao_object_reference->get_subclass ();"
+ // << nl;
if (!bpd || (bpd->pt () != AST_PredefinedType::PT_void))
{
cg->push (TAO_CodeGen::TAO_OPERATION_RETVAL_ASSIGN_SS);
diff --git a/TAO/TAO_IDL/be/be_string.cpp b/TAO/TAO_IDL/be/be_string.cpp
index 811c83166e8..3ea2d4f3997 100644
--- a/TAO/TAO_IDL/be/be_string.cpp
+++ b/TAO/TAO_IDL/be/be_string.cpp
@@ -72,7 +72,6 @@ int
be_string::gen_client_header (void)
{
TAO_OutStream *ch; // output stream
- TAO_NL nl; // end line
// retrieve a singleton instance of the code generator
TAO_CodeGen *cg = TAO_CODEGEN::instance ();
diff --git a/TAO/TAO_IDL/be_include/be.h b/TAO/TAO_IDL/be_include/be.h
index b89376d8347..a1ec674be84 100644
--- a/TAO/TAO_IDL/be_include/be.h
+++ b/TAO/TAO_IDL/be_include/be.h
@@ -51,8 +51,8 @@ Technical Data and Computer Software clause at DFARS 252.227-7013 and FAR
Sun, Sun Microsystems and the Sun logo are trademarks or registered
trademarks of Sun Microsystems, Inc.
-SunSoft, Inc.
-2550 Garcia Avenue
+SunSoft, Inc.
+2550 Garcia Avenue
Mountain View, California 94043
NOTE:
@@ -79,6 +79,7 @@ trademarks or registered trademarks of Sun Microsystems, Inc.
#include "ace/Singleton.h"
#include "ace/Synch.h"
#include "ace/Log_Msg.h"
+#include "ace/Containers.h"
/*
* BE includes
@@ -108,7 +109,7 @@ trademarks or registered trademarks of Sun Microsystems, Inc.
#include "be_array.h" // class BE_Array
#include "be_sequence.h" // class BE_Sequence
#include "be_string.h" // class BE_String
-#include "be_typedef.h" // class BE_Typedef
+#include "be_typedef.h" // class BE_Typedef
#include "be_root.h" // class BE_Root
#include "be_helper.h" // helper functions
diff --git a/TAO/TAO_IDL/be_include/be_interface.h b/TAO/TAO_IDL/be_include/be_interface.h
index 2e997dc0685..584a1bae6ce 100644
--- a/TAO/TAO_IDL/be_include/be_interface.h
+++ b/TAO/TAO_IDL/be_include/be_interface.h
@@ -21,6 +21,8 @@
#if !defined (TAO_BE_INTERFACE_H)
#define TAO_BE_INTERFACE_H
+class TAO_OutStream;
+
/*
* BE_Interface
*/
@@ -34,6 +36,10 @@ class be_interface : public virtual AST_Interface,
// = DESCRIPTION
//
public:
+
+ // used to pass functions to the template method
+ typedef int (*tao_code_emitter) (be_interface *, be_interface *, TAO_OutStream *);
+
// Operations
be_interface (void);
// Default constructor
@@ -88,6 +94,10 @@ public:
virtual long tc_encap_len (void);
// return length of encapsulation
+ virtual int traverse_inheritance_graph (tao_code_emitter gen,
+ TAO_OutStream *os);
+ // template method using breadth first traversal of inheritance graph
+
// Narrowing
DEF_NARROW_METHODS3 (be_interface, AST_Interface, be_scope, be_type);
DEF_NARROW_FROM_DECL (be_interface);
@@ -97,10 +107,28 @@ private:
void compute_fullskelname (void);
// compute the fully scoped skel class name
- // helper methods for the C++ mapping process
int gen_operation_table (void);
+ // generate the operation table including entries for inherited interfaces
+
+ int gen_optable_entries (be_interface *);
+ // generate the operation table entries
+
+ static int is_a_helper (be_interface *, be_interface *, TAO_OutStream *os);
+ // helper method passed to the template method
+
+ static int gen_optable_helper (be_interface *,
+ be_interface *,
+ TAO_OutStream *os);
+ // helper method passed to the template method
+
+ static int gen_skel_helper (be_interface *,
+ be_interface *,
+ TAO_OutStream *os);
+ // helper method passed to the template method
char *full_skel_name_; // fully scoped skeleton name
+
+ int skel_count_; // number of static skeletons in the operation table
};
#endif // if !defined