summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--TAO/TAO_IDL/be/be_global.cpp30
-rw-r--r--TAO/TAO_IDL/be/be_interface.cpp105
-rw-r--r--TAO/TAO_IDL/be/be_visitor_root.cpp1
-rw-r--r--TAO/TAO_IDL/be/be_visitor_root/root.cpp19
-rw-r--r--TAO/TAO_IDL/be/be_visitor_template_export.cpp122
-rw-r--r--TAO/TAO_IDL/be_include/be_global.h10
-rw-r--r--TAO/TAO_IDL/be_include/be_visitor_template_export.h57
7 files changed, 298 insertions, 46 deletions
diff --git a/TAO/TAO_IDL/be/be_global.cpp b/TAO/TAO_IDL/be/be_global.cpp
index cd160fcd5b6..7db39ced0c5 100644
--- a/TAO/TAO_IDL/be/be_global.cpp
+++ b/TAO/TAO_IDL/be/be_global.cpp
@@ -112,7 +112,8 @@ BE_GlobalData::BE_GlobalData (void)
gen_client_stub_ (true),
gen_server_skeleton_ (true),
gen_local_iface_anyops_ (true),
- use_clonable_in_args_ (false)
+ use_clonable_in_args_ (false),
+ gen_template_export_ (false)
{
}
@@ -850,6 +851,18 @@ BE_GlobalData::use_clonable_in_args (void) const
return this->use_clonable_in_args_;
}
+bool
+BE_GlobalData::gen_template_export (void) const
+{
+ return this->gen_template_export_;
+}
+
+void
+BE_GlobalData::gen_template_export (bool val)
+{
+ this->gen_template_export_ = val;
+}
+
const char*
BE_GlobalData::anyop_header_ending (void) const
{
@@ -1294,6 +1307,8 @@ BE_GlobalData::ccmobject (void)
AST_Decl *d =
idl_global->scopes ().top_non_null ()->lookup_by_name (&sn,
+ true,
+ true,
true);
sn.destroy ();
@@ -1973,6 +1988,11 @@ BE_GlobalData::parse_args (long &i, char **av)
// Smart proxies.
be_global->gen_smart_proxies (true);
}
+ else if (av[i][3] == 'e')
+ {
+ // Explicit sequence base class template export.
+ be_global->gen_template_export (true);
+ }
else
{
ACE_ERROR ((
@@ -2623,8 +2643,12 @@ BE_GlobalData::usage (void) const
ACE_DEBUG ((
LM_DEBUG,
ACE_TEXT (" -Guc\t\t\tgenerate uninlined constant if declared ")
- ACE_TEXT ("in a module")
- ACE_TEXT (" (inlined by default)\n")
+ ACE_TEXT ("in a module (inlined by default)\n")
+ ));
+ ACE_DEBUG ((
+ LM_DEBUG,
+ ACE_TEXT (" -Gse\t\t\tgenerate explicit export of sequence's ")
+ ACE_TEXT ("template base class (not generated by default)\n")
));
ACE_DEBUG ((
LM_DEBUG,
diff --git a/TAO/TAO_IDL/be/be_interface.cpp b/TAO/TAO_IDL/be/be_interface.cpp
index 6fc79e08fe7..5d9bd60218d 100644
--- a/TAO/TAO_IDL/be/be_interface.cpp
+++ b/TAO/TAO_IDL/be/be_interface.cpp
@@ -502,7 +502,8 @@ be_interface::gen_def_ctors_helper (be_interface* node,
}
else
{
- *os << ", " << be_global->impl_class_prefix () << base->flat_name ()
+ *os << ", " << be_global->impl_class_prefix ()
+ << base->flat_name ()
<< be_global->impl_class_suffix () << " ()";
}
}
@@ -762,8 +763,8 @@ Pure_Virtual_Regenerator::emit (be_interface *derived_interface,
if (d->accept (this->visitor_) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
- "(%N:%l) Pure_Virtual_Regenerator::emit - "
- "visit base interface operation failed\n"),
+ "(%N:%l) Pure_Virtual_Regenerator::emit - "
+ "visit base interface operation failed\n"),
-1);
}
@@ -921,7 +922,8 @@ be_interface::gen_operation_table (const char *flat_name,
// interface.
// Retrieve the singleton instance to the outstream factory.
- TAO_OutStream_Factory *factory = TAO_OUTSTREAM_FACTORY::instance ();
+ TAO_OutStream_Factory *factory =
+ TAO_OUTSTREAM_FACTORY::instance ();
// Get a new instance for the temp file.
TAO_OutStream *os = factory->make_outstream ();
@@ -1291,7 +1293,8 @@ be_interface::gen_collocated_skel_body (be_interface *derived,
*os << be_nl << be_nl
<< "ACE_INLINE void" << be_nl
<< derived->full_direct_proxy_impl_name ()
- << "::" << prefix << d->local_name () << " (" << be_idt << be_idt_nl
+ << "::" << prefix << d->local_name () << " ("
+ << be_idt << be_idt_nl
<< "TAO_Abstract_ServantBase *servant," << be_nl
<< "TAO::Argument ** args," << be_nl
<< "int num_args" << env_decl << be_uidt_nl
@@ -1302,7 +1305,8 @@ be_interface::gen_collocated_skel_body (be_interface *derived,
*os << be_uidt_nl
<< "{" << be_idt_nl
<< ancestor->full_direct_proxy_impl_name ()
- << "::" << prefix << d->local_name () << " (" << be_idt << be_idt_nl
+ << "::" << prefix << d->local_name () << " ("
+ << be_idt << be_idt_nl
<< "servant," << be_nl
<< "args," << be_nl
<< "num_args" << env_arg << be_uidt_nl
@@ -1380,8 +1384,8 @@ be_interface::traverse_inheritance_graph (be_interface::tao_code_emitter gen,
if (insert_queue.enqueue_tail (this) == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
- "(%N:%l) be_interface::traverse_inheritance_graph - "
- "error generating entries\n"),
+ "(%N:%l) be_interface::traverse_inheritance_graph"
+ " - error generating entries\n"),
-1);
}
@@ -1653,11 +1657,14 @@ be_interface::gen_gperf_lookup_methods (const char *flat_name)
"fclose"),
-1);
}
-
+
// Open the temp file.
#if defined (ACE_OPENVMS)
- ACE_HANDLE input = ::open(tao_cg->gperf_input_filename(), O_RDONLY,
- "shr=get,put,upd", "ctx=rec", "fop=dfw");
+ ACE_HANDLE input = ::open (tao_cg->gperf_input_filename (),
+ O_RDONLY,
+ "shr=get,put,upd",
+ "ctx=rec",
+ "fop=dfw");
#else
ACE_HANDLE input = ACE::open_temp_file (tao_cg->gperf_input_filename (),
O_RDONLY);
@@ -1682,14 +1689,20 @@ be_interface::gen_gperf_lookup_methods (const char *flat_name)
// this, remember to update the file offset to the correct location.
#if defined (ACE_OPENVMS)
- char* gperfOutput = tempnam(NULL, "idl_");
- if (gperfOutput == NULL)
+ char* gperfOutput = tempnam (0, "idl_");
+
+ if (gperfOutput == 0)
{
- ACE_OS::close(input);
- ACE_ERROR_RETURN ((LM_ERROR, "failed to allocate memory\n"), -1);
+ ACE_OS::close (input);
+ ACE_ERROR_RETURN ((LM_ERROR, "failed to allocate memory\n"), -1);
}
- ACE_HANDLE output = ::open(gperfOutput, O_WRONLY | O_CREAT | O_EXCL,
- ACE_DEFAULT_FILE_PERMS , "shr=get,put,upd", "ctx=rec", "fop=dfw");
+
+ ACE_HANDLE output = ::open (gperfOutput,
+ O_WRONLY | O_CREAT | O_EXCL,
+ ACE_DEFAULT_FILE_PERMS ,
+ "shr=get,put,upd",
+ "ctx=rec",
+ "fop=dfw");
#else
ACE_HANDLE output = ACE_OS::open (this->strategy_->get_out_stream_fname (),
O_WRONLY | O_APPEND);
@@ -1785,7 +1798,8 @@ be_interface::gen_gperf_lookup_methods (const char *flat_name)
default:
ACE_ERROR ((LM_ERROR,
- "tao_idl:ERROR:%N:%l:Unknown Operation Lookup Strategy\n"));
+ "tao_idl:ERROR:%N:%l:Unknown "
+ "Operation Lookup Strategy\n"));
result = -1;
}
@@ -1806,7 +1820,8 @@ be_interface::gen_gperf_lookup_methods (const char *flat_name)
else if (process.wait () == -1)
{
ACE_ERROR ((LM_ERROR,
- "Error:%p:Error on waiting for completion of gperf program.\n",
+ "Error:%p:Error on waiting for "
+ "completion of gperf program.\n",
"process.wait"));
result = -1;
@@ -1814,7 +1829,7 @@ be_interface::gen_gperf_lookup_methods (const char *flat_name)
// Adjust the file offset to the EOF for the server skeleton
// file.
- ACE_OS::fseek (this->strategy_->get_out_stream()->file (),
+ ACE_OS::fseek (this->strategy_->get_out_stream ()->file (),
0,
SEEK_END);
}
@@ -1822,13 +1837,15 @@ be_interface::gen_gperf_lookup_methods (const char *flat_name)
ACE_OS::close (output);
ACE_OS::close (input);
-#if defined(ACE_OPENVMS)
- ACE_OS::unlink(tao_cg->gperf_input_filename());
- process_options.release_handles();
+#if defined (ACE_OPENVMS)
+ ACE_OS::unlink(tao_cg->gperf_input_filename ());
+ process_options.release_handles ();
+
if (result != -1)
{
FILE* gperfOutputFile;
- gperfOutputFile = ::fopen(gperfOutput, "r");
+ gperfOutputFile = ::fopen (gperfOutput, "r");
+
if (gperfOutputFile == 0)
{
ACE_ERROR ((LM_ERROR,
@@ -1838,24 +1855,28 @@ be_interface::gen_gperf_lookup_methods (const char *flat_name)
}
else
{
- FILE* out = this->strategy_->get_out_stream()->file();
+ FILE* out = this->strategy_->get_out_stream ()->file ();
int c;
+
while ((c = fgetc(gperfOutputFile)) != EOF)
{
- fputc(c, out);
+ fputc (c, out);
}
- if (ferror(gperfOutputFile) || ferror(out))
+
+ if (ferror (gperfOutputFile) || ferror (out))
{
ACE_ERROR ((LM_ERROR,
"Error:%p:Couldn't open gperf output file\n",
"get/put"));
result = -1;
}
- fclose(gperfOutputFile);
+
+ fclose (gperfOutputFile);
}
}
- ACE_OS::unlink(gperfOutput);
- free(gperfOutput);
+
+ ACE_OS::unlink (gperfOutput);
+ free (gperfOutput);
#endif /* ACE_OPENVMS */
return result;
@@ -1942,9 +1963,9 @@ be_interface::gen_skel_helper (be_interface *derived,
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.
+ // attributes defined by "ancestor", become methods on the derived
+ // class which call the corresponding method of the base class by
+ // doing the proper casting.
for (UTL_ScopeActiveIterator si (ancestor, UTL_Scope::IK_decls);
!si.is_done ();
@@ -1955,10 +1976,10 @@ be_interface::gen_skel_helper (be_interface *derived,
if (d->node_type () == AST_Decl::NT_op)
{
- *os << be_nl << be_nl << "// TAO_IDL - Generated from" << be_nl
- << "// " << __FILE__ << ":" << __LINE__;
-
- *os << be_nl << be_nl;
+ *os << be_nl << be_nl
+ << "// TAO_IDL - Generated from" << be_nl
+ << "// " << __FILE__ << ":" << __LINE__
+ << be_nl << be_nl;
if (os->stream_type () == TAO_OutStream::TAO_SVR_HDR)
{
@@ -2182,7 +2203,8 @@ be_interface::gen_colloc_op_decl_helper (be_interface *derived,
// Generate the static method corresponding to
// this method.
*os << "static void" << be_nl
- << "_set_" << d->local_name () << " (" << be_idt << be_idt_nl
+ << "_set_" << d->local_name () << " ("
+ << be_idt << be_idt_nl
<< "TAO_Abstract_ServantBase *servant, " << be_nl
<< "TAO::Argument ** args," << be_nl
<< "int num_args" << env_dflts << be_uidt_nl
@@ -2434,7 +2456,7 @@ be_interface::destroy (void)
delete this->strategy_;
this->strategy_ = 0;
}
-
+
// Call the destroy methods of our base classes.
this->AST_Interface::destroy ();
this->be_scope::destroy ();
@@ -2457,7 +2479,8 @@ be_interface::next_state (TAO_CodeGen::CG_STATE current_state,
}
int
-be_interface::has_extra_code_generation (TAO_CodeGen::CG_STATE current_state)
+be_interface::has_extra_code_generation (
+ TAO_CodeGen::CG_STATE current_state)
{
return this->strategy_->has_extra_code_generation (current_state);
}
@@ -2489,7 +2512,7 @@ be_interface::has_mixed_parentage (void)
}
AST_Decl::NodeType nt = this->node_type ();
-
+
if (AST_Decl::NT_component == nt || AST_Decl::NT_home == nt)
{
return 0;
diff --git a/TAO/TAO_IDL/be/be_visitor_root.cpp b/TAO/TAO_IDL/be/be_visitor_root.cpp
index 3cee0de1265..b88712b67f5 100644
--- a/TAO/TAO_IDL/be/be_visitor_root.cpp
+++ b/TAO/TAO_IDL/be/be_visitor_root.cpp
@@ -59,6 +59,7 @@
#include "be_visitor_home.h"
#include "be_visitor_traits.h"
#include "be_visitor_arg_traits.h"
+#include "be_visitor_template_export.h"
#include "be_visitor_context.h"
#include "be_visitor_root/root.cpp"
diff --git a/TAO/TAO_IDL/be/be_visitor_root/root.cpp b/TAO/TAO_IDL/be/be_visitor_root/root.cpp
index 44ae5a92566..74b1174c595 100644
--- a/TAO/TAO_IDL/be/be_visitor_root/root.cpp
+++ b/TAO/TAO_IDL/be/be_visitor_root/root.cpp
@@ -272,8 +272,8 @@ int be_visitor_root::visit_root (be_root *node)
{
case TAO_CodeGen::TAO_ROOT_CH:
{
- be_visitor_traits visitor (&ctx);
- status = node->accept (&visitor);
+ be_visitor_traits traits_visitor (&ctx);
+ status = node->accept (&traits_visitor);
if (status == -1)
{
@@ -283,6 +283,21 @@ int be_visitor_root::visit_root (be_root *node)
"failed to generate traits\n"),
-1);
}
+
+ if (be_global->gen_template_export ())
+ {
+ be_visitor_template_export export_visitor (&ctx);
+ status = node->accept (&export_visitor);
+
+ if (status == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_visitor_root::"
+ "visit_root - "
+ "failed to export templates\n"),
+ -1);
+ }
+ }
}
break;
diff --git a/TAO/TAO_IDL/be/be_visitor_template_export.cpp b/TAO/TAO_IDL/be/be_visitor_template_export.cpp
new file mode 100644
index 00000000000..a14875b5fa5
--- /dev/null
+++ b/TAO/TAO_IDL/be/be_visitor_template_export.cpp
@@ -0,0 +1,122 @@
+//=============================================================================
+/**
+* @file be_visitor_template_export.cpp
+*
+* $Id$
+*
+* This visitor generates template instantiations with export macro
+*
+* @author Jeff Parsons <j.parsons@vanderbilt.edu>
+*/
+//=============================================================================
+
+#include "be_visitor_template_export.h"
+#include "be_visitor_context.h"
+#include "be_root.h"
+#include "be_module.h"
+#include "be_typedef.h"
+#include "be_sequence.h"
+#include "be_extern.h"
+#include "be_helper.h"
+
+ACE_RCSID (be,
+ be_visitor_template_export,
+ "$Id$")
+
+be_visitor_template_export::be_visitor_template_export (
+ be_visitor_context *ctx)
+ : be_visitor_scope (ctx)
+{
+}
+
+be_visitor_template_export::~be_visitor_template_export (void)
+{
+}
+
+int
+be_visitor_template_export::visit_root (be_root *node)
+{
+ TAO_OutStream *os = this->ctx_->stream ();
+
+ *os << "// TAO_IDL - Generated from " << be_nl
+ << "// " << __FILE__ << ":" << __LINE__ << be_nl << be_nl;
+
+ *os << "// Workaround for a Visual Studio .NET bug where this class is not" << be_nl
+ << "// properly imported by an application if typedef'd or subclassed," << be_nl
+ << "// resulting in 'multiply defined' link errors. The export macro" << be_nl
+ << "// here forces an explicit import by the application. Please see" << be_nl
+ << "// http://support.microsoft.com/default.aspx?scid=kb;en-us;309801" << be_nl
+ << "// The problem stems from use of the type below in PortableServer," << be_nl
+ << "// but we put the instantiation here because the application will" << be_nl
+ << "// need to see it in *C.h to avoid the error." << be_nl
+ << "#if defined ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT" << be_idt;
+
+ if (this->visit_scope (node) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "be_visitor_template_export::"
+ "visit_root - visit scope failed\n"),
+ -1);
+ }
+
+ *os << be_uidt_nl
+ << "#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION_EXPORT */";
+
+ return 0;
+}
+
+int
+be_visitor_template_export::visit_module (be_module *node)
+{
+ if (this->visit_scope (node) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "be_visitor_template_export::"
+ "visit_module - visit scope failed\n"),
+ -1);
+ }
+
+ return 0;
+}
+
+int
+be_visitor_template_export::visit_sequence (be_sequence *node)
+{
+ TAO_OutStream *os = this->ctx_->stream ();
+
+ *os << be_nl
+ << "template class " << be_global->stub_export_macro ()
+ << " ";
+
+ if (node->gen_base_class_name (os, "", this->ctx_->scope ()) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_visitor_template_export::"
+ "visit_sequence - "
+ "Base class name generation failed\n"),
+ -1);
+ }
+
+ *os << ";";
+
+ return 0;
+}
+
+int
+be_visitor_template_export::visit_typedef (be_typedef *node)
+{
+ this->ctx_->alias (node);
+ be_type *bt = node->primitive_base_type ();
+
+ if (bt->accept (this) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "be_visitor_template_export::"
+ "visit_typedef - "
+ "visit base type failed\n"),
+ -1);
+ }
+
+ this->ctx_->alias (0);
+ return 0;
+}
diff --git a/TAO/TAO_IDL/be_include/be_global.h b/TAO/TAO_IDL/be_include/be_global.h
index f29df3a6175..24ee713d4c5 100644
--- a/TAO/TAO_IDL/be_include/be_global.h
+++ b/TAO/TAO_IDL/be_include/be_global.h
@@ -329,6 +329,12 @@ public:
bool use_clonable_in_args (void) const;
// Get the clonable_in_args setting.
+ bool gen_template_export (void) const;
+ // Get the gen_seq_template_export_ member.
+
+ void gen_template_export (bool val);
+ // Set the gen_seq_template_export_ member.
+
const char* anyop_header_ending (void) const;
// Get the anyop_header_ending.
@@ -788,6 +794,10 @@ private:
bool use_clonable_in_args_;
// Use in_clonable_arg_val instead of in_arg_val?
+
+ bool gen_template_export_;
+ // Generate explicit export for Visual Studio bug workaround,
+ // needed only in TAO basic sequence *C.h files.
};
#endif /* _BE_GLOBAL_H */
diff --git a/TAO/TAO_IDL/be_include/be_visitor_template_export.h b/TAO/TAO_IDL/be_include/be_visitor_template_export.h
new file mode 100644
index 00000000000..1f74232c376
--- /dev/null
+++ b/TAO/TAO_IDL/be_include/be_visitor_template_export.h
@@ -0,0 +1,57 @@
+//
+// $Id$
+//
+
+/* -*- c++ -*- */
+// ============================================================================
+//
+// = LIBRARY
+// TAO IDL
+//
+// = FILENAME
+// be_visitor_template_export.h
+//
+// = DESCRIPTION
+// This visitor generates an explicit export of a sequence's
+// template base class. It is conditionally launched by a
+// command line option and is motivated by a bug in Visual
+// Studio C++ (.NET 2002, .NET 2003, and Express 2005), documented in
+// http://support.microsoft.com/default.aspx?scid=kb;en-us;309801
+//
+// = AUTHOR
+// Jeff Parsons <j.parsons@vanderbilt.edu>
+//
+// ============================================================================
+
+#ifndef TAO_BE_VISITOR_TEMPLATE_EXPORT_H
+#define TAO_BE_VISITOR_TEMPLATE_EXPORT_H
+
+#include "be_visitor_scope.h"
+
+class AST_Interface;
+
+class be_visitor_template_export : public be_visitor_scope
+{
+ //
+ // = TITLE
+ // be_visitor_template_export
+ //
+ // = DESCRIPTION
+ // Generates sequence template base class export instantiation.
+ //
+public:
+ be_visitor_template_export (be_visitor_context *ctx);
+
+ virtual ~be_visitor_template_export (void);
+
+ virtual int visit_root (be_root *node);
+
+ virtual int visit_module (be_module *node);
+
+ virtual int visit_typedef (be_typedef *node);
+
+ virtual int visit_sequence (be_sequence *node);
+};
+
+
+#endif // TAO_BE_VISITOR_TEMPLATE_EXPORT_H