diff options
-rw-r--r-- | TAO/TAO_IDL/be/be_global.cpp | 30 | ||||
-rw-r--r-- | TAO/TAO_IDL/be/be_interface.cpp | 105 | ||||
-rw-r--r-- | TAO/TAO_IDL/be/be_visitor_root.cpp | 1 | ||||
-rw-r--r-- | TAO/TAO_IDL/be/be_visitor_root/root.cpp | 19 | ||||
-rw-r--r-- | TAO/TAO_IDL/be/be_visitor_template_export.cpp | 122 | ||||
-rw-r--r-- | TAO/TAO_IDL/be_include/be_global.h | 10 | ||||
-rw-r--r-- | TAO/TAO_IDL/be_include/be_visitor_template_export.h | 57 |
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 |