diff options
Diffstat (limited to 'modules/CIAO/tools/IDL3_to_IDL2')
20 files changed, 4471 insertions, 0 deletions
diff --git a/modules/CIAO/tools/IDL3_to_IDL2/IDL3_to_IDL2.mpc b/modules/CIAO/tools/IDL3_to_IDL2/IDL3_to_IDL2.mpc new file mode 100644 index 00000000000..0ca14095a49 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/IDL3_to_IDL2.mpc @@ -0,0 +1,72 @@ +// -*- MPC -*- +// $Id$ + +project(TAO_IDL3_TO_IDL2_BE) : acelib, install, ciao_output, crosscompile { + after += TAO_IDL_FE + sharedname = TAO_IDL3_TO_IDL2_BE + libs += TAO_IDL_FE + dynamicflags = TAO_IDL3_TO_IDL2_BE_BUILD_DLL + includes += $(TAO_ROOT)/TAO_IDL/include $(TAO_ROOT)/TAO_IDL/fe + + // This is necessary for MPC to pull in rules.ciao.GNU + includes += $(CIAO_ROOT) + + Source_Files { + basic_visitor.cpp + be_global.cpp + be_helper.cpp + be_init.cpp + be_produce.cpp + be_sunsoft.cpp + checking_visitor.cpp + identifier_helper.cpp + idl3_to_idl2_visitor.cpp + } + + Header_Files { + basic_visitor.h + be_extern.h + be_global.h + be_helper.h + be_sunsoft.h + checking_visitor.h + identifier_helper.h + idl3_to_idl2_visitor.h + TAO_IDL3_TO_IDL2_BE_Export.h + } +} + +project(TAO_IDL3_TO_IDL2_EXE) : aceexe, install, ciao_output, crosscompile, tao_idl_mcpp { + after += TAO_IDL3_TO_IDL2_BE TAO_IDL_FE + exename = tao_idl3_to_idl2 + libs += TAO_IDL3_TO_IDL2_BE TAO_IDL_FE + includes += . $(TAO_ROOT)/TAO_IDL/include \ + $(TAO_ROOT)/TAO_IDL/fe \ + $(TAO_ROOT) + libpaths += $(TAO_ROOT)/TAO_IDL + exeout = $(CIAO_ROOT)/bin + + // Adding a strict ordering dependency with TAO_IDL_EXE. It appears on some systems, there + // can be a race between these two projects for tao_idl.cpp, causing some erroors. + after += TAO_IDL_EXE + + // This is necessary for MPC to pull in rules.ciao.GNU + includes += $(CIAO_ROOT) + + verbatim(gnuace, local) { + ifeq ($(TAO_IDL_PREPROCESSOR),) + CPPFLAGS += -DTAO_IDL_PREPROCESSOR=\\\"$(strip $(CXX))\\\" + else + CPPFLAGS += -DTAO_IDL_PREPROCESSOR=\\\"$(subst \\,\\,$(TAO_IDL_PREPROCESSOR))\\\" + endif + } + + Source_Files { + $(TAO_ROOT)/TAO_IDL/driver/drv_args.cpp + $(TAO_ROOT)/TAO_IDL/tao_idl.cpp + } + + Header_Files { + $(TAO_ROOT)/TAO_IDL/include/drv_extern.h + } +} diff --git a/modules/CIAO/tools/IDL3_to_IDL2/README b/modules/CIAO/tools/IDL3_to_IDL2/README new file mode 100644 index 00000000000..23ebd734b7e --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/README @@ -0,0 +1,138 @@ + + IDL3 To IDL2 Converter + +A pluggable back end used with the IDL compiler parser +and command line processor, this tool converts CCM-related +IDL constructs into their corresponding IDL2 equivalents, +in a new IDL file. For more information about CIAO and the CIAO +CIDL compiler, please see + +$CIAO_ROOT/docs/releasenotes/index.html + +COMPILING: + +Use the provided .mpc file to generate a project or makefile to +compile the pluggable back end library and the executable. +Make sure the TAO IDL compiler front end is already built. + +EXECUTABLE NAME: + +tao_idl3_to_idl2 + +COMMAND LINE OPTIONS: + +All the usual front-end command line options that apply to the IDL compiler +(such as path includes) work with this tool as well, since the IDL compiler +front end is simply reused. The options -? or -h will display a usage +message, including both front end and back end options. For a complete +list of IDL compiler command line options and a description of each, see +TAO/docs/compiler.html. + +BACKEND OPTIONS: + +-o <path> Also works the same as with the IDL compiler, setting the +output directory, overriding the default, which is the directory of +execution. + +-x <filename> Excludes included IDL file <filename> from having its +corresponding include generated with an '_IDL2' suffix. This feature +is to be used when an included IDL file cannot or need not be +itself coverted by this tool. + +-e Generates a file foo_IDL2.idl from foo.idl that simply includes +foo.idl instead of generating its IDL declarations. Note that this +option takes effect only if foo.idl contains no 'IDL3' declarations, +otherwise it's a no-op. + +CAVEAT: + +When using the TAO IDL compiler on files that are generated by this tool, +use the command line option -Sm on the IDL compiler, which will disable +the internal generation of equivalent IDL nodes in the AST. You'll notice +from the example below that the only ones that remain are eventtypes. +The -Sm option will prevent the IDL compiler from trying to create the +corresponding xxxConsumer interface, which now already exists explicitly +in IDL. + +EXAMPLE CONVERSION: + + +// test.idl + +#include <Components.idl> + +interface Foo {}; + +eventtype Ev {}; + +component Bar +{ + uses multiple Foo needs_foo; + publishes Ev ev_pub; +}; + +home BarHome manages Bar +{ +}; + + +Typing + +tao_idl3_to_idl2 -I<CIAO_ROOT>/ciao -I<TAO_ROOT> test.idl + +will generate + + + +// test_IDL2.idl + +#include "Components.idl" + +interface Foo {}; + +eventtype Ev {}; + +interface EvConsumer : Components::EventConsumerBase +{ + void push_Ev (in Ev the_Ev); +}; + +interface Bar : Components::CCMObject +{ + struct needs_fooConnection + { + Foo objref; + Components::Cookie ck; + }; + + typedef sequence<needs_fooConnection> needs_fooConnections; + + Components::Cookie connect_needs_foo (in Foo connection) + raises (Components::ExceededConnectionLimit, Components::InvalidConnection); + + Foo disconnect_needs_foo (in Components::Cookie ck) + raises (Components::InvalidConnection); + + needs_fooConnections get_connections_needs_foo (); + + Components::Cookie subscribe_ev_pub (in EvConsumer consumer) + raises (Components::ExceededConnectionLimit); + + EvConsumer unsubscribe_ev_pub (in Components::Cookie ck) + raises (Components::InvalidConnection); +}; + +interface BarHomeExplicit : Components::CCMHome +{ +}; + +interface BarHomeImplicit : Components::KeylessCCMHome +{ + Bar create () + raises (Components::CreateFailure); +}; + +interface BarHome : BarHomeExplicit, BarHomeImplicit +{ +}; + diff --git a/modules/CIAO/tools/IDL3_to_IDL2/TAO_IDL3_TO_IDL2_BE_Export.h b/modules/CIAO/tools/IDL3_to_IDL2/TAO_IDL3_TO_IDL2_BE_Export.h new file mode 100644 index 00000000000..7b54e254326 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/TAO_IDL3_TO_IDL2_BE_Export.h @@ -0,0 +1,58 @@ + +// -*- C++ -*- +// $Id$ +// Definition for Win32 Export directives. +// This file is generated automatically by generate_export_file.pl TAO_IDL3_TO_IDL2_BE +// ------------------------------ +#ifndef TAO_IDL3_TO_IDL2_BE_EXPORT_H +#define TAO_IDL3_TO_IDL2_BE_EXPORT_H + +#include "ace/config-all.h" + +#if defined (ACE_AS_STATIC_LIBS) && !defined (TAO_IDL3_TO_IDL2_BE_HAS_DLL) +# define TAO_IDL3_TO_IDL2_BE_HAS_DLL 0 +#endif /* ACE_AS_STATIC_LIBS && TAO_IDL3_TO_IDL2_BE_HAS_DLL */ + +#if !defined (TAO_IDL3_TO_IDL2_BE_HAS_DLL) +# define TAO_IDL3_TO_IDL2_BE_HAS_DLL 1 +#endif /* ! TAO_IDL3_TO_IDL2_BE_HAS_DLL */ + +#if defined (TAO_IDL3_TO_IDL2_BE_HAS_DLL) && (TAO_IDL3_TO_IDL2_BE_HAS_DLL == 1) +# if defined (TAO_IDL3_TO_IDL2_BE_BUILD_DLL) +# define TAO_IDL3_TO_IDL2_BE_Export ACE_Proper_Export_Flag +# define TAO_IDL3_TO_IDL2_BE_SINGLETON_DECLARATION(T) ACE_EXPORT_SINGLETON_DECLARATION (T) +# define TAO_IDL3_TO_IDL2_BE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_EXPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# else /* TAO_IDL3_TO_IDL2_BE_BUILD_DLL */ +# define TAO_IDL3_TO_IDL2_BE_Export ACE_Proper_Import_Flag +# define TAO_IDL3_TO_IDL2_BE_SINGLETON_DECLARATION(T) ACE_IMPORT_SINGLETON_DECLARATION (T) +# define TAO_IDL3_TO_IDL2_BE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) ACE_IMPORT_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +# endif /* TAO_IDL3_TO_IDL2_BE_BUILD_DLL */ +#else /* TAO_IDL3_TO_IDL2_BE_HAS_DLL == 1 */ +# define TAO_IDL3_TO_IDL2_BE_Export +# define TAO_IDL3_TO_IDL2_BE_SINGLETON_DECLARATION(T) +# define TAO_IDL3_TO_IDL2_BE_SINGLETON_DECLARE(SINGLETON_TYPE, CLASS, LOCK) +#endif /* TAO_IDL3_TO_IDL2_BE_HAS_DLL == 1 */ + +// Set TAO_IDL3_TO_IDL2_BE_NTRACE = 0 to turn on library specific tracing even if +// tracing is turned off for ACE. +#if !defined (TAO_IDL3_TO_IDL2_BE_NTRACE) +# if (ACE_NTRACE == 1) +# define TAO_IDL3_TO_IDL2_BE_NTRACE 1 +# else /* (ACE_NTRACE == 1) */ +# define TAO_IDL3_TO_IDL2_BE_NTRACE 0 +# endif /* (ACE_NTRACE == 1) */ +#endif /* !TAO_IDL3_TO_IDL2_BE_NTRACE */ + +#if (TAO_IDL3_TO_IDL2_BE_NTRACE == 1) +# define TAO_IDL3_TO_IDL2_BE_TRACE(X) +#else /* (TAO_IDL3_TO_IDL2_BE_NTRACE == 1) */ +# if !defined (ACE_HAS_TRACE) +# define ACE_HAS_TRACE +# endif /* ACE_HAS_TRACE */ +# define TAO_IDL3_TO_IDL2_BE_TRACE(X) ACE_TRACE_IMPL(X) +# include "ace/Trace.h" +#endif /* (TAO_IDL3_TO_IDL2_BE_NTRACE == 1) */ + +#endif /* TAO_IDL3_TO_IDL2_BE_EXPORT_H */ + +// End of auto generated file. diff --git a/modules/CIAO/tools/IDL3_to_IDL2/basic_visitor.cpp b/modules/CIAO/tools/IDL3_to_IDL2/basic_visitor.cpp new file mode 100644 index 00000000000..a444f67794c --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/basic_visitor.cpp @@ -0,0 +1,1158 @@ +/* -*- c++ -*- */ +// $Id$ + +#include "basic_visitor.h" +#include "identifier_helper.h" +#include "be_sunsoft.h" +#include "be_extern.h" + +#include "ast_argument.h" +#include "ast_array.h" +#include "ast_attribute.h" +#include "ast_enum.h" +#include "ast_enum_val.h" +#include "ast_exception.h" +#include "ast_factory.h" +#include "ast_field.h" +#include "ast_operation.h" +#include "ast_root.h" +#include "ast_sequence.h" +#include "ast_string.h" +#include "ast_structure_fwd.h" +#include "ast_union.h" +#include "ast_union_branch.h" +#include "ast_union_fwd.h" +#include "ast_union_label.h" +#include "ast_valuebox.h" +#include "ast_valuetype.h" +#include "ast_valuetype_fwd.h" +#include "ast_native.h" +#include "utl_exceptlist.h" +#include "utl_idlist.h" +#include "utl_identifier.h" +#include "nr_extern.h" + +basic_visitor::basic_visitor (void) + : os (0), + disc_type_ (0) +{ +} + +basic_visitor::~basic_visitor (void) +{ + delete this->os; + this->os = 0; +} + +int +basic_visitor::visit_decl (AST_Decl *) +{ + return 0; +} + +int +basic_visitor::visit_scope (UTL_Scope *node) +{ + for (UTL_ScopeActiveIterator si (node, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + AST_Decl *d = si.item (); + + if (this->scope_skip_type (d)) + { + continue; + } + + // Want to skip the uses_xxxConnection structs added by uses + // multiple ports. + // @@@ (JP) This will go away when the visitor is finished, since + // those uses_xxxConnection structs will not be added to the AST. + if (ScopeAsDecl (node)->node_type () == AST_Decl::NT_component + && d->node_type () != AST_Decl::NT_attr) + { + continue; + } + + if (d->ast_accept (this) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "idl3_to_idl2_visitor::visit_scope - " + "codegen for scope failed\n"), + -1); + } + } + + return 0; +} + +int +basic_visitor::visit_type (AST_Type *) +{ + return 0; +} + +int +basic_visitor::visit_predefined_type (AST_PredefinedType *) +{ + return 0; +} + +int +basic_visitor::visit_interface_fwd (AST_InterfaceFwd *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl; + + if (node->is_local ()) + { + *os << "local "; + } + + if (node->is_abstract ()) + { + *os << "abstract "; + } + + *os << "interface " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str () + << ";"; + + return 0; +} + +int +basic_visitor::visit_valuebox (AST_ValueBox *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl + << "valuetype " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str (); + + AST_Type *bt = node->boxed_type (); + + // Keep output statements separate because of side effects. + + if (bt->node_type () == AST_Decl::NT_array) + { + this->gen_anonymous_array (bt, node); + } + else + { + *os << this->type_name (bt); + } + + *os << ";"; + + this->check_id_and_version (node); + + return 0; +} + +int +basic_visitor::visit_valuetype (AST_ValueType *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl; + + if (node->is_abstract ()) + { + *os << "abstract "; + } + + if (node->custom ()) + { + *os << "custom "; + } + + *os << "valuetype " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str (); + + AST_Decl::NodeType nt = node->node_type (); + AST_Interface **parents = node->inherits (); + long ninherits = node->n_inherits (); + + long i = 0; + for (i = 0; i < ninherits; ++i) + { + if (i == 0) + { + *os << " : "; + } + else + { + *os << ", "; + } + + *os << IdentifierHelper::orig_sn (parents[i]->name ()).c_str (); + } + + if (nt == AST_Decl::NT_eventtype) + { + *os << (ninherits == 0 ? " : " : ", ") + << "Components::EventBase"; + } + + AST_Interface **supports = node->supports (); + + for (i = 0; i < node->n_supports (); ++i) + { + if (i == 0) + { + *os << " supports "; + } + else + { + *os << ", "; + } + + *os << IdentifierHelper::orig_sn (supports[i]->name ()).c_str (); + } + + *os << be_nl + << "{" << be_idt; + + this->check_id_and_version (node); + this->check_prefix (node); + + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "idl3_to_idl2_visitor::visit_valuetype - " + "codegen for scope failed\n"), + -1); + } + + *os << be_uidt_nl + << "};"; + + return 0; +} + +int +basic_visitor::visit_valuetype_fwd (AST_ValueTypeFwd *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl; + + if (node->is_abstract ()) + { + *os << "abstract "; + } + + (void) node->node_type (); + + *os << "valuetype " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str () + << ";"; + + return 0; +} + +int +basic_visitor::visit_factory (AST_Factory *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl; + + *os << "factory " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str () + << " ("; + + this->gen_params (node, node->argument_count ()); + + *os << ")"; + + this->gen_exception_list (node->exceptions ()); + + *os << ";"; + + this->check_id_and_version (node); + + return 0; +} + +int +basic_visitor::visit_structure (AST_Structure *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl; + + *os << "struct " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str () + << be_nl + << "{" << be_idt; + + this->check_id_and_version (node); + + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "idl3_to_idl2_visitor::visit_structure - " + "codegen for scope failed\n"), + -1); + } + + *os << be_uidt_nl + << "};"; + + return 0; +} + +int +basic_visitor::visit_structure_fwd (AST_StructureFwd *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl; + + *os << "struct " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str () + << ";"; + + return 0; +} + +int +basic_visitor::visit_exception (AST_Exception *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl; + + *os << "exception " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str () + << be_nl + << "{" << be_idt; + + this->check_id_and_version (node); + + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "idl3_to_idl2_visitor::visit_exception - " + "codegen for scope failed\n"), + -1); + } + + *os << be_uidt_nl + << "};"; + + return 0; +} + +int +basic_visitor::visit_expression (AST_Expression *) +{ + return 0; +} + +int +basic_visitor::visit_enum (AST_Enum *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl; + + *os << "enum " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str () + << be_nl + << "{" << be_idt; + + for (UTL_ScopeActiveIterator i (node, UTL_Scope::IK_decls); + !i.is_done ();) + { + *os << be_nl; + + AST_EnumVal *ev = AST_EnumVal::narrow_from_decl (i.item ()); + + *os << IdentifierHelper::try_escape (ev->original_local_name ()).c_str (); + + // Advance here so the check below will work. + i.next (); + + if (!i.is_done ()) + { + *os << ","; + } + } + + *os << be_uidt_nl + << "};"; + + this->check_id_and_version (node); + + return 0; +} + +int +basic_visitor::visit_operation (AST_Operation *node) +{ + this->gen_operation (node); + this->check_id_and_version (node); + + return 0; +} + +int +basic_visitor::visit_field (AST_Field *node) +{ + AST_Field::Visibility v = node->visibility (); + + *os << be_nl + << (v == AST_Field::vis_PUBLIC + ? "public " + : (v == AST_Field::vis_PRIVATE ? "private " : "")); + + AST_Type *ft = node->field_type (); + + if (ft->node_type () == AST_Decl::NT_array) + { + this->gen_anonymous_array (ft, node); + } + else + { + // Keep these statements separate because of side effects. + *os << this->type_name (ft); + *os << " " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str (); + } + + *os << ";"; + + return 0; +} + +int +basic_visitor::visit_argument (AST_Argument *node) +{ + *os << be_nl; + + switch (node->direction ()) + { + case AST_Argument::dir_IN: + *os << "in "; + break; + case AST_Argument::dir_INOUT: + *os << "inout "; + break; + case AST_Argument::dir_OUT: + *os << "out "; + break; + default: + return -1; + } + + *os << this->type_name (node->field_type ()) + << " " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str (); + + return 0; +} + +int +basic_visitor::visit_attribute (AST_Attribute *node) +{ + this->gen_attribute (node); + this->check_id_and_version (node); + + return 0; +} + +int +basic_visitor::visit_union (AST_Union *node) +{ + if (node->imported ()) + { + return 0; + } + + this->disc_type_ = node->disc_type ()->unaliased_type (); + + *os << be_nl << be_nl + << "union " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str () + << " switch ("; + + *os << this->type_name (node->disc_type ()) + << ")" << be_nl + << "{" << be_idt; + + this->check_id_and_version (node); + + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "idl3_to_idl2_visitor::visit_union - " + "codegen for scope failed\n"), + -1); + } + + *os << be_uidt_nl + << "};"; + + return 0; +} + +int +basic_visitor::visit_union_fwd (AST_UnionFwd *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl + << "union " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str () + << ";"; + + return 0; +} + +int +basic_visitor::visit_union_branch (AST_UnionBranch *node) +{ + for (unsigned long i = 0; i < node->label_list_length (); ++i) + { + if (this->visit_union_label (node->label (i)) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "idl3_to_idl2_visitor::visit_union_branch - " + "codegen for label failed\n"), + -1); + } + } + + AST_Type *ft = node->field_type (); + + if (ft->node_type () == AST_Decl::NT_array) + { + this->gen_anonymous_array (ft, node); + } + else + { + *os << this->type_name (ft); + *os << " " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str (); + } + + *os << ";"; + + return 0; +} + +int +basic_visitor::visit_union_label (AST_UnionLabel *node) +{ + *os << be_nl; + + if (node->label_kind () == AST_UnionLabel::UL_default) + { + *os << "default: "; + } + else + { + *os << "case "; + this->gen_label_value (node); + *os << ": "; + } + + return 0; +} + +int +basic_visitor::visit_constant (AST_Constant *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl; + + *os << "const "; + + switch (node->et ()) + { + case AST_Expression::EV_short: + *os << "short"; + break; + case AST_Expression::EV_ushort: + *os << "unsigned short"; + break; + case AST_Expression::EV_long: + *os << "long"; + break; + case AST_Expression::EV_ulong: + *os << "unsigned long"; + break; + case AST_Expression::EV_longlong: + *os << "long long"; + break; + case AST_Expression::EV_ulonglong: + *os << "unsigned long long"; + break; + case AST_Expression::EV_char: + *os << "char"; + break; + case AST_Expression::EV_wchar: + *os << "wchar"; + break; + case AST_Expression::EV_bool: + *os << "boolean"; + break; + case AST_Expression::EV_octet: + *os << "octet"; + break; + case AST_Expression::EV_float: + *os << "float"; + break; + case AST_Expression::EV_double: + *os << "double"; + break; + case AST_Expression::EV_longdouble: + *os << "long double"; + break; + case AST_Expression::EV_string: + *os << "string"; + break; + case AST_Expression::EV_wstring: + *os << "wstring"; + break; + case AST_Expression::EV_enum: + *os << IdentifierHelper::orig_sn (node->enum_full_name ()).c_str (); + break; + default: + break; + } + + *os << " " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str () + << " = " << node->constant_value () << ";"; + + this->check_id_and_version (node); + + return 0; +} + +int +basic_visitor::visit_enum_val (AST_EnumVal *) +{ + return 0; +} + +int +basic_visitor::visit_array (AST_Array *node) +{ + *os << IdentifierHelper::orig_sn (node->base_type ()->name ()).c_str (); + + for (unsigned long i = 0; i < node->n_dims (); ++i) + { + *os << "[" << node->dims ()[i] << "]"; + } + + return 0; +} + +int +basic_visitor::visit_sequence (AST_Sequence *node) +{ + // Keep output statements separate because of side effects. + *os << "sequence<"; + *os << this->type_name (node->base_type ()); + + if (!node->unbounded ()) + { + *os << ", " << node->max_size ()->ev ()->u.ulval; + } + + *os << "> "; + + return 0; +} + +int +basic_visitor::visit_string (AST_String *node) +{ + *os << (node->width () > 1 ? "w" : "") << "string"; + + unsigned long bound = node->max_size ()->ev ()->u.ulval; + + if (bound > 0) + { + *os << "<" << bound << ">"; + } + + return 0; +} + +int +basic_visitor::visit_typedef (AST_Typedef *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl + << "typedef "; + + AST_Type *bt = node->base_type (); + + // Keep output statements separate because of side effects. + + if (bt->node_type () == AST_Decl::NT_array) + { + this->gen_anonymous_array (bt, node); + } + else + { + *os << this->type_name (bt); + *os << " " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str (); + } + + *os << ";"; + + this->check_id_and_version (node); + + return 0; +} + +int +basic_visitor::visit_native (AST_Native *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl; + + *os << "native " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str () + << ";"; + + return 0; +} + +//======================================================== + +void +basic_visitor::check_prefix (AST_Decl *d) +{ + if (d->typeid_set ()) + { + return; + } + + const char *the_prefix = d->prefix (); + AST_Decl *p = ScopeAsDecl (d->defined_in ()); + + if (ACE_OS::strcmp (the_prefix, p->prefix ()) != 0) + { + *os << be_nl + << "typeprefix " + << IdentifierHelper::try_escape (d->original_local_name ()).c_str () + << " \"" << the_prefix << "\";"; + } +} + +void +basic_visitor::check_id_and_version (AST_Decl *d) +{ + if (d->typeid_set ()) + { + *os << be_nl + << "typeid " + << IdentifierHelper::try_escape (d->original_local_name ()).c_str () + << " \"" << d->repoID () << "\";"; + + return; + } + + const char *the_version = d->version (); + AST_Decl *p = ScopeAsDecl (d->defined_in ()); + + if (ACE_OS::strcmp (the_version, p->version ()) != 0) + { + *os << "\n" + << "#pragma version " + << IdentifierHelper::try_escape (d->original_local_name ()).c_str () + << " " << the_version; + } +} + +const char * +basic_visitor::type_name (AST_Type *t) +{ + AST_PredefinedType *pdt = 0; + + switch (t->node_type ()) + { + case AST_Decl::NT_wstring: + case AST_Decl::NT_string: + case AST_Decl::NT_sequence: + // This causes side effects so output statements + // sending us here should not be concatenated. + (void) t->ast_accept (this); + return ""; + case AST_Decl::NT_pre_defined: + pdt = AST_PredefinedType::narrow_from_decl (t); + + switch (pdt->pt ()) + { + case AST_PredefinedType::PT_pseudo: + return t->full_name (); + case AST_PredefinedType::PT_object: + return "Object"; + case AST_PredefinedType::PT_any: + return "any"; + case AST_PredefinedType::PT_long: + return "long"; + case AST_PredefinedType::PT_ulong: + return "unsigned long"; + case AST_PredefinedType::PT_longlong: + return "long long"; + case AST_PredefinedType::PT_ulonglong: + return "unsigned long long"; + case AST_PredefinedType::PT_short: + return "short"; + case AST_PredefinedType::PT_ushort: + return "unsigned short"; + case AST_PredefinedType::PT_float: + return "float"; + case AST_PredefinedType::PT_double: + return "double"; + case AST_PredefinedType::PT_longdouble: + return "long double"; + case AST_PredefinedType::PT_char: + return "char"; + case AST_PredefinedType::PT_wchar: + return "wchar"; + case AST_PredefinedType::PT_boolean: + return "boolean"; + case AST_PredefinedType::PT_octet: + return "octet"; + case AST_PredefinedType::PT_void: + return "void"; + default: + break; + } + default: + this->tmp_retval_ = IdentifierHelper::orig_sn (t->name ()).c_str (); + return this->tmp_retval_.c_str (); + } +} + +void +basic_visitor::gen_anonymous_array (AST_Type *a, + AST_Decl *wrapper) +{ + AST_Array *array = AST_Array::narrow_from_decl (a); + AST_Type *bt = array->base_type (); + + *os << this->type_name (bt); + *os << " " + << IdentifierHelper::try_escape (wrapper->original_local_name ()).c_str (); + + for (unsigned long i = 0; i < array->n_dims (); ++i) + { + *os << "[" << array->dims ()[i]->ev ()->u.ulval << "]"; + } +} + +void +basic_visitor::gen_params (UTL_Scope *s, int arg_count) +{ + if (arg_count > 0) + { + *os << be_idt << be_idt; + + for (UTL_ScopeActiveIterator si (s, UTL_Scope::IK_decls); + !si.is_done ();) + { + if (si.item ()->ast_accept (this) != 0) + { + ACE_ERROR ((LM_ERROR, + "idl3_to_idl2_visitor::gen_params - " + "codegen for parameters failed\n")); + } + + si.next (); + + if (!si.is_done ()) + { + *os << ","; + } + } + + *os << be_uidt_nl << be_uidt; + } +} + +void +basic_visitor::gen_exception_list (UTL_ExceptList *exceptions, + const char *prefix, + bool closed) +{ + if (exceptions != 0 && exceptions->length () > 0) + { + *os << be_idt_nl + << prefix << "raises ("; + + for (UTL_ExceptlistActiveIterator ei (exceptions); + !ei.is_done ();) + { + *os << IdentifierHelper::orig_sn (ei.item ()->name ()).c_str (); + + ei.next (); + + if (!ei.is_done () || !closed) + { + *os << ", "; + } + } + + if (closed) + { + *os << ")" << be_uidt; + } + } +} + +void +basic_visitor::gen_operation (AST_Operation *node) +{ + *os << be_nl << be_nl; + + if (node->flags () == AST_Operation::OP_oneway) + { + *os << "oneway "; + } + + *os << this->type_name (node->return_type ()); + + *os << " " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str () + << " ("; + + this->gen_params (node, node->argument_count ()); + + *os << ")"; + + this->gen_exception_list (node->exceptions ()); + + *os << ";"; +} + +void +basic_visitor::gen_attribute (AST_Attribute *node) +{ + bool rd_only = node->readonly (); + + // Keep output statements separate because of side effects. + // No need to check for anonymous array - anonymous types not + // accepted by parser for attributes. + *os << be_nl << be_nl + << (rd_only ? "readonly " : "") << "attribute "; + *os << this->type_name (node->field_type ()); + *os << " " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str (); + + this->gen_exception_list (node->get_get_exceptions (), + rd_only ? "" : "get"); + + this->gen_exception_list (node->get_set_exceptions (), + "set"); + + *os << ";"; +} + +void +basic_visitor::gen_label_value (AST_UnionLabel *node) +{ + AST_Expression *val = node->label_val (); + AST_Expression::AST_ExprValue *ev = val->ev (); + + if (this->disc_type_->node_type () == AST_Decl::NT_enum) + { + UTL_Scope *s = this->disc_type_->defined_in (); + + if (s == 0) + { + *os << IdentifierHelper::orig_sn (val->n ()).c_str (); + } + else + { + *os << IdentifierHelper::orig_sn (ScopeAsDecl (s)->name ()).c_str () + << "::"; + + Identifier *id = + IdentifierHelper::original_local_name (val->n ()->last_component ()); + + *os << IdentifierHelper::try_escape (id).c_str (); + + id->destroy (); + delete id; + id = 0; + } + + return; + } + + switch (ev->et) + { + case AST_Expression::EV_short: + *os << ev->u.sval; + break; + case AST_Expression::EV_ushort: + *os << ev->u.usval; + break; + case AST_Expression::EV_long: + *os << ev->u.lval; + break; + case AST_Expression::EV_ulong: + *os << ev->u.ulval; + break; + case AST_Expression::EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) + this->os->print ("%lld", ev->u.llval); +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + break; + case AST_Expression::EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) + *os << "ACE_UINT64_LITERAL ("; + this->os->print (ACE_UINT64_FORMAT_SPECIFIER_ASCII, ev->u.ullval); + *os << ")"; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + break; + case AST_Expression::EV_char: + *os << ev->u.cval; + break; + case AST_Expression::EV_wchar: + *os << ev->u.wcval; + break; + case AST_Expression::EV_bool: + *os << (ev->u.bval ? "TRUE" : "FALSE"); + break; + case AST_Expression::EV_enum: + *os << IdentifierHelper::orig_sn (val->n ()).c_str (); + break; + default: + break; + } +} + +bool +basic_visitor::scope_skip_type (AST_Decl *d) +{ + return (d->node_type () == AST_Decl::NT_pre_defined); +} + +bool +basic_visitor::can_skip_module (AST_Module *m) +{ + for (UTL_ScopeActiveIterator si (m, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + AST_Decl *d = si.item (); + AST_Decl::NodeType nt = d->node_type (); + + switch (nt) + { + case AST_Decl::NT_interface: + case AST_Decl::NT_interface_fwd: + case AST_Decl::NT_component: + case AST_Decl::NT_component_fwd: + case AST_Decl::NT_eventtype: + case AST_Decl::NT_eventtype_fwd: + case AST_Decl::NT_home: + if (d->is_abstract () || d->is_local ()) + { + break; + } + + return false; + case AST_Decl::NT_module: + if (!this->can_skip_module (AST_Module::narrow_from_decl (d))) + { + return false; + } + + break; + default: + break; + } + } + + return true; +} + +bool +basic_visitor::match_excluded_file (const char *raw_filename) +{ + ACE_CString::size_type p = 0; + + // If this included IDL file matches one of the 'excluded' files, + // generate the include without tacking on the suffix. + while (p != ACE_CString::npos) + { + ACE_CString::size_type cursor = p; + p = be_global->excluded_filenames ().find (' ', cursor); + + ACE_CString one_filename = + be_global->excluded_filenames ().substr (cursor, p - cursor); + + if (one_filename == raw_filename) + { + return true; + } + + // Skip the whitespace. + if (p != ACE_CString::npos) + { + while (be_global->excluded_filenames ()[p] == ' ') + { + p++; + } + } + } + + return false; +} diff --git a/modules/CIAO/tools/IDL3_to_IDL2/basic_visitor.h b/modules/CIAO/tools/IDL3_to_IDL2/basic_visitor.h new file mode 100644 index 00000000000..418ab0d5dcc --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/basic_visitor.h @@ -0,0 +1,114 @@ +// $Id$ + +/* -*- c++ -*- */ +// ============================================================================ +// +// = LIBRARY +// TAO_IDL3_TO_IDL2_BE_DLL +// +// = FILENAME +// basic_visitor.h +// +// = DESCRIPTION +// Base class for other visitors in this backend. +// +// ============================================================================ + +#ifndef TAO_BASIC_VISITOR_H +#define TAO_BASIC_VISITOR_H + +#include "ast_visitor.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "TAO_IDL3_TO_IDL2_BE_Export.h" + +#include "ace/SString.h" + +class TAO_OutStream; +class UTL_ExceptList; + +class TAO_IDL3_TO_IDL2_BE_Export basic_visitor : public ast_visitor +{ + // + // = TITLE + // basic_visitor. + // + // = DESCRIPTION + // Base class for visitors in this backend and others. + // +public: + basic_visitor (void); + virtual ~basic_visitor (void); + + virtual int visit_decl (AST_Decl *d); + virtual int visit_scope (UTL_Scope *node); + virtual int visit_type (AST_Type *node); + virtual int visit_predefined_type (AST_PredefinedType *node); + virtual int visit_module (AST_Module *node) = 0; + virtual int visit_interface (AST_Interface *node) = 0; + virtual int visit_interface_fwd (AST_InterfaceFwd *node); + virtual int visit_valuebox (AST_ValueBox *node); + virtual int visit_valuetype (AST_ValueType *node); + virtual int visit_valuetype_fwd (AST_ValueTypeFwd *node); + virtual int visit_component (AST_Component *node) = 0; + virtual int visit_component_fwd (AST_ComponentFwd *node) = 0; + virtual int visit_eventtype (AST_EventType *node) = 0; + virtual int visit_eventtype_fwd (AST_EventTypeFwd *node) = 0; + virtual int visit_home (AST_Home *node) = 0; + virtual int visit_factory (AST_Factory *node); + virtual int visit_structure (AST_Structure *node); + virtual int visit_structure_fwd (AST_StructureFwd *node); + virtual int visit_exception (AST_Exception *node); + virtual int visit_expression (AST_Expression *node); + virtual int visit_enum (AST_Enum *node); + virtual int visit_operation (AST_Operation *node); + virtual int visit_field (AST_Field *node); + virtual int visit_argument (AST_Argument *node); + virtual int visit_attribute (AST_Attribute *node); + virtual int visit_union (AST_Union *node); + virtual int visit_union_fwd (AST_UnionFwd *node); + virtual int visit_union_branch (AST_UnionBranch *node); + virtual int visit_union_label (AST_UnionLabel *node); + virtual int visit_constant (AST_Constant *node); + virtual int visit_enum_val (AST_EnumVal *node); + virtual int visit_array (AST_Array *node); + virtual int visit_sequence (AST_Sequence *node); + virtual int visit_string (AST_String *node); + virtual int visit_typedef (AST_Typedef *node); + virtual int visit_root (AST_Root *node) = 0; + virtual int visit_native (AST_Native *node); + +protected: + void check_prefix (AST_Decl *d); + void check_id_and_version (AST_Decl *d); + const char *type_name (AST_Type *t); + void gen_anonymous_array (AST_Type *array, AST_Decl *wrapper); + void gen_params (UTL_Scope *s, int arg_count); + void gen_exception_list (UTL_ExceptList *exceptions, + const char *prefix = "", + bool closed = true); + void gen_operation (AST_Operation *node); + void gen_attribute (AST_Attribute *node); + void gen_label_value (AST_UnionLabel *node); + + // Overrides allow common code for visit_scope(). + virtual bool scope_skip_type (AST_Decl *d); + + // Used by derived visitors to avoid generating an empty IDL module. + bool can_skip_module (AST_Module *m); + + // Used by derived visitors to check for special include handling. + bool match_excluded_file (const char *raw_filename); + +protected: + TAO_OutStream *os; + AST_Type *disc_type_; + +private: + ACE_CString tmp_retval_; +}; + +#endif // TAO_BASIC_VISITOR_H diff --git a/modules/CIAO/tools/IDL3_to_IDL2/be_extern.h b/modules/CIAO/tools/IDL3_to_IDL2/be_extern.h new file mode 100644 index 00000000000..c7dc3daaf41 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/be_extern.h @@ -0,0 +1,86 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ +/* + +COPYRIGHT + +Copyright 1992, 1993, 1994 Sun Microsystems, Inc. Printed in the United +States of America. All Rights Reserved. + +This product is protected by copyright and distributed under the following +license restricting its use. + +The Interface Definition Language Compiler Front End (CFE) is made +available for your use provided that you include this license and copyright +notice on all media and documentation and the software program in which +this product is incorporated in whole or part. You may copy and extend +functionality (but may not remove functionality) of the Interface +Definition Language CFE without charge, but you are not authorized to +license or distribute it to anyone else except as part of a product or +program developed by you or with the express written consent of Sun +Microsystems, Inc. ("Sun"). + +The names of Sun Microsystems, Inc. and any of its subsidiaries or +affiliates may not be used in advertising or publicity pertaining to +distribution of Interface Definition Language CFE as permitted herein. + +This license is effective until terminated by Sun for failure to comply +with this license. Upon termination, you shall destroy or return all code +and documentation for the Interface Definition Language CFE. + +INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED AS IS WITH NO WARRANTIES OF +ANY KIND INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS +FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR ARISING FROM A COURSE OF +DEALING, USAGE OR TRADE PRACTICE. + +INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED WITH NO SUPPORT AND WITHOUT +ANY OBLIGATION ON THE PART OF Sun OR ANY OF ITS SUBSIDIARIES OR AFFILIATES +TO ASSIST IN ITS USE, CORRECTION, MODIFICATION OR ENHANCEMENT. + +SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES SHALL HAVE NO LIABILITY WITH +RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY +INTERFACE DEFINITION LANGUAGE CFE OR ANY PART THEREOF. + +IN NO EVENT WILL SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES BE LIABLE FOR +ANY LOST REVENUE OR PROFITS OR OTHER SPECIAL, INDIRECT AND CONSEQUENTIAL +DAMAGES, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +Use, duplication, or disclosure by the government is subject to +restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in +Technical Data and Computer Software clause at DFARS 252.227-7013 and FAR +52.227-19. + +Sun, Sun Microsystems and the Sun logo are trademarks or registered +trademarks of Sun Microsystems, Inc. + +SunSoft, Inc. +2550 Garcia Avenue +Mountain View, California 94043 + +NOTE: + +SunOS, SunSoft, Sun, Solaris, Sun Microsystems or the Sun logo are +trademarks or registered trademarks of Sun Microsystems, Inc. + +*/ + +#ifndef TAO_IFR_BE_EXTERN_H +#define TAO_IFR_BE_EXTERN_H + +#include "TAO_IDL3_TO_IDL2_BE_Export.h" +#include "be_global.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +extern TAO_IDL3_TO_IDL2_BE_Export BE_GlobalData *be_global; + +extern TAO_IDL3_TO_IDL2_BE_Export int BE_init (int &, ACE_TCHAR*[]); +extern TAO_IDL3_TO_IDL2_BE_Export void BE_post_init (char *[], long); +extern TAO_IDL3_TO_IDL2_BE_Export void BE_version (void); +extern TAO_IDL3_TO_IDL2_BE_Export void BE_produce (void); +extern TAO_IDL3_TO_IDL2_BE_Export void BE_cleanup (void); +extern TAO_IDL3_TO_IDL2_BE_Export void BE_abort (void); + +#endif /* TAO_IFR_BE_EXTERN_H */ diff --git a/modules/CIAO/tools/IDL3_to_IDL2/be_global.cpp b/modules/CIAO/tools/IDL3_to_IDL2/be_global.cpp new file mode 100644 index 00000000000..4aa8ba19182 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/be_global.cpp @@ -0,0 +1,224 @@ +// $Id$ + +// ============================================================================ +// +// +// = LIBRARY +// TAO_IDL3_TO_IDL2L_BE_DLL +// +// = FILENAME +// be_global.cpp +// +// = DESCRIPTION +// Stores global data specific to the compiler back end. +// +// = AUTHOR +// Jeff Parsons <j.parsons@vanderbilt.edu> +// +// ============================================================================ + +#include "be_global.h" +#include "be_sunsoft.h" +#include "ast_generator.h" +#include "global_extern.h" +#include "idl_defines.h" +#include "utl_string.h" +#include "idl3_to_idl2_visitor.h" + +#include "ace/OS_NS_stdio.h" + +TAO_IDL3_TO_IDL2_BE_Export BE_GlobalData *be_global = 0; + +BE_GlobalData::BE_GlobalData (void) + : gen_copyright_ (true), + filename_ (0), + output_dir_ (0), + encapsulate_idl2_ (false) +{ +} + +BE_GlobalData::~BE_GlobalData (void) +{ +} + +const char * +BE_GlobalData::filename (void) const +{ + return this->filename_; +} + +void +BE_GlobalData::filename (char *fname) +{ + this->filename_ = fname; +} + +const char* +BE_GlobalData::output_dir (void) const +{ + return this->output_dir_; +} + +void +BE_GlobalData::output_dir (const char* s) +{ + delete [] this->output_dir_; + this->output_dir_ = ACE::strnew (s); +} + +bool +BE_GlobalData::encapsulate_idl2 (void) const +{ + return this->encapsulate_idl2_; +} + +ACE_CString & +BE_GlobalData::excluded_filenames (void) +{ + return this->excluded_filenames_; +} + +bool +BE_GlobalData::gen_copyright (void) const +{ + return this->gen_copyright_; +} + +void +BE_GlobalData::parse_args (long &i, char **av) +{ + switch (av[i][1]) + { + // Directory where the generated file is to + // be kept. Default is the current directory from which + // <tao_idl3_to_idl2> is called. + case 'o': + if (av[i][2] == '\0') + { + this->output_dir (av [i + 1]); + i++; + } + else + { + this->output_dir (av[i] + 2); + } + break; + case 'x': + if (this->excluded_filenames_ != "") + { + this->excluded_filenames_ += " "; + } + + if (av[i][2] == '\0') + { + this->excluded_filenames_ += av [i + 1]; + i++; + } + else + { + this->excluded_filenames_ += av[i] + 2; + } + break; + case 'e': + this->encapsulate_idl2_ = true; + break; + default: + ACE_ERROR (( + LM_ERROR, + ACE_TEXT ("IDL: I don't understand the '%s' option\n"), + av[i] + )); + + idl_global->set_compile_flags (idl_global->compile_flags () + | IDL_CF_ONLY_USAGE); + break; + } +} + +// Prepare an argument for a BE. +void +BE_GlobalData::prep_be_arg (char *) +{ +} + +void +BE_GlobalData::arg_post_proc (void) +{ +} + +void +BE_GlobalData::usage (void) const +{ + ACE_DEBUG (( + LM_DEBUG, + ACE_TEXT (" -o <dir>\t\tOutput directory for the generated file.") + ACE_TEXT (" Default is current directory\n") + )); + ACE_DEBUG (( + LM_DEBUG, + ACE_TEXT (" -x <filename>\t\tIncluded IDL file that wasn't processed") + ACE_TEXT (" by this tool (regenerate include directive unchanged)\n") + )); + ACE_DEBUG (( + LM_DEBUG, + ACE_TEXT (" -e\t\t\tGenerate just an include of original IDL file") + ACE_TEXT (" if no IDL3 declarations are found\n") + )); +} + +AST_Generator * +BE_GlobalData::generator_init (void) +{ + AST_Generator *gen = 0; + ACE_NEW_RETURN (gen, + AST_Generator, + 0); + return gen; +} + +int +BE_GlobalData::outfile_init (TAO_OutStream *& os, + const char *file_prefix, + const char *file_suffix, + const char *guard_prefix, + const char *guard_suffix) +{ + ACE_NEW_RETURN (os, + TAO_SunSoft_OutStream, + -1); + + ACE_CString fn (idl_global->stripped_filename ()->get_string ()); + fn = fn.substr (0, fn.rfind ('.')); + fn += file_suffix; + + const char *path = be_global->output_dir (); + ACE_CString target_name; + + if (path != 0) + { + target_name = path; + target_name += "/"; + } + + target_name += file_prefix; + target_name += fn; + + if (os->open (target_name.c_str ()) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "Failed to open file %s for writing.\n", + target_name.c_str ()), + -1); + } + + *os << be_nl; + + os->gen_ifndef_string (fn.c_str (), guard_prefix, guard_suffix); + + return 0; +} + +void +BE_GlobalData::destroy (void) +{ +} diff --git a/modules/CIAO/tools/IDL3_to_IDL2/be_global.h b/modules/CIAO/tools/IDL3_to_IDL2/be_global.h new file mode 100644 index 00000000000..21d1e41af3e --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/be_global.h @@ -0,0 +1,118 @@ +/* -*- c++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO_IFR_BE_DLL +// +// = FILENAME +// be_global.h +// +// = DESCRIPTION +// Header file for class containing compiler back end global data. +// +// = AUTHOR +// Jeff Parsons <parsons@cs.wustl.edu> +// +// ============================================================================ + +#ifndef TAO_IFR_BE_GLOBAL_H +#define TAO_IFR_BE_GLOBAL_H + +#include "TAO_IDL3_TO_IDL2_BE_Export.h" +#include "idl_defines.h" +#include "ace/SString.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +class AST_Generator; +class TAO_OutStream; + +// Defines a class containing all back end global data. + +class TAO_IDL3_TO_IDL2_BE_Export BE_GlobalData +{ +public: + // = TITLE + // BE_GlobalData + // + // = DESCRIPTION + // Storage of global data specific to the compiler back end + // + BE_GlobalData (void); + // Constructor. + + virtual ~BE_GlobalData (void); + // Destructor. + + //======================================= + + // Data accessors. + + const char *filename (void) const; + void filename (char *fname); + + const char* output_dir (void) const; + void output_dir (const char* s); + + bool encapsulate_idl2 (void) const; + + ACE_CString & excluded_filenames (void); + + bool gen_copyright (void) const; + + //========================================= + + virtual void parse_args (long &i, char **av); + // Parse args that affect this backend. + + void prep_be_arg (char *s); + // Special BE arg call factored out of DRV_args. + + void arg_post_proc (void); + // Checks made after parsing args. + + virtual void usage (void) const; + // Usage message for backend options. + + AST_Generator *generator_init (void); + // Create an AST node generator. + + int outfile_init (TAO_OutStream *&, + const char *file_prefix, + const char *file_suffix, + const char *guard_prefix, + const char *guard_suffix); + // Create the output file, the associated stream, and + // generate the initial #ifndef. + + void destroy (void); + // Cleanup. + +protected: + bool gen_copyright_; + // So it can be turned off in backends that inherit from this one. + +private: + char *filename_; + // Name of the IDL file we are processing. + + char *output_dir_; + // Directory where the generated file is to be + // kept. Default value is 0 for this string which means the current + // directory from which the <tao_picml> is called. + + bool encapsulate_idl2_; + // Have the generated file just include the original file if + // no IDL3 declarations are found by the checking visitor. + + ACE_CString excluded_filenames_; + // Whitespace-separated list of included IDL files + // to be passed to the output IDL file without + // adding the '_IDL2" suffix. +}; + +#endif /* TAO_IFR_BE_GLOBAL_H */ diff --git a/modules/CIAO/tools/IDL3_to_IDL2/be_helper.cpp b/modules/CIAO/tools/IDL3_to_IDL2/be_helper.cpp new file mode 100644 index 00000000000..db3968af3c5 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/be_helper.cpp @@ -0,0 +1,435 @@ +// $Id$ + +// ============================================================================ +// +// +// = LIBRARY +// TAO IDL +// +// = FILENAME +// be_helper.cpp +// +// = DESCRIPTION +// Provides helper classes to print generated code to the output +// +// = AUTHOR +// Aniruddha Gokhale +// +// Improvements by Carlos O'Ryan +// +// ============================================================================ + +#include "be_helper.h" +#include "be_extern.h" +#include "idl_defines.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_ctype.h" + +ACE_RCSID (be, + be_helper, + "$Id$") + +static const char copyright[] = +"// -*- C++ -*-\n" +"//\n" +"// $I" "d$\n\n" +"// **** Code generated by the The Component Integrated ACE ORB (CIAO)" +" IDL3 to IDL2 Compiler ****\n" +"// CIAO and this tool have been developed by:\n" +"// Center for Distributed Object Computing\n" +"// Washington University\n" +"// St. Louis, MO\n" +"// USA\n" +"// http://www.cs.wustl.edu/~schmidt/doc-center.html\n" +"// and\n" +"// Distributed Object Computing Laboratory\n" +"// University of California at Irvine\n" +"// Irvine, CA\n" +"// USA\n" +"// http://doc.ece.uci.edu/\n" +"// and\n" +"// Institute for Software Integrated Systems\n" +"// Vanderbilt University\n" +"// Nashville, TN\n" +"// USA\n" +"// http://www.isis.vanderbilt.edu/\n" +"//\n" +"// Information about CIAO is available at:\n" +"// http://www.cs.wustl.edu/~schmidt/CIAO.html"; + +TAO_NL::TAO_NL (void) +{ +} + +TAO_INDENT::TAO_INDENT (int do_now) + : do_now_ (do_now) +{ +} + +TAO_UNINDENT::TAO_UNINDENT (int do_now) + : do_now_ (do_now) +{ +} + +const TAO_NL be_nl; +const TAO_INDENT be_idt; +const TAO_INDENT be_idt_nl (1); +const TAO_UNINDENT be_uidt; +const TAO_UNINDENT be_uidt_nl (1); + +// Methods of the TAO_OutStream class. + +TAO_OutStream::TAO_OutStream (void) + : fp_ (0), + indent_level_ (0) +{ +} + +TAO_OutStream::~TAO_OutStream (void) +{ + // Close the underlying I/O handle only if it exists. + if (this->fp_ != 0) + { + ACE_OS::fclose (this->fp_); + this->fp_ = 0; + } + + indent_level_ = 0; +} + +int +TAO_OutStream::open (const char *fname) +{ + if (fname != 0) + { + // File name exists, open an I/O file handle. + this->fp_ = ACE_OS::fopen (fname, "w"); + + if (this->fp_ != 0) + { + if (be_global->gen_copyright ()) + { + // Put the copyright notice. + ACE_OS::fprintf (this->fp_, + "%s\n", + copyright); + + ACE_OS::fflush (this->fp_); + } + + return 0; + } + else + { + return -1; + } + } + else + { + return -1; + } +} + +// Return the underlying lowlevel file pointer. +// indentation. +FILE * +TAO_OutStream::file (void) +{ + return this->fp_; +} + +int +TAO_OutStream::incr_indent (unsigned short flag) +{ + indent_level_++; + + if (flag != 0) + { + return this->indent (); + } + else + { + // Do not indent output. + return 0; + } +} + +// Indentation +int +TAO_OutStream::decr_indent (unsigned short flag) +{ + this->indent_level_--; + // Just in case somebody gets "unindent happy". + if (this->indent_level_ < 0) + { + // ACE_DEBUG ((LM_DEBUG, "negative indentation?\n")); + this->indent_level_ = 0; + } + if (flag != 0) + { + return this->indent (); + } + else + { + // Do not indent output. + return 0; + } +} + +int +TAO_OutStream::reset (void) +{ + this->indent_level_ = 0; + return 0; +} + +// Indented print. +int +TAO_OutStream::indent (void) +{ + // Based on the current indentation level, leave appropriate number of blank + // spaces in the output. + if (this->indent_level_ > 0) + { + for (int i = 0; i < this->indent_level_; i++) + { + ACE_OS::fprintf (this->fp_, " "); + ACE_OS::fflush (this->fp_); + } + } + + return 0; +} + +int +TAO_OutStream::nl (void) +{ + ACE_OS::fprintf (this->fp_, "\n"); + this->indent (); + return 0; +} + +// Printf style variable argument print. +int +TAO_OutStream::print (const char *format, ...) +{ + int result = 0; + va_list ap; + va_start (ap, format); + ACE_OSCALL (::vfprintf (this->fp_, + format, + ap), + int, + -1, + result); + + ACE_OS::fflush (this->fp_); + va_end (ap); + + return result; +} + +void +TAO_OutStream::gen_ifndef_string (const char *fname, + const char *prefix, + const char *suffix) +{ + static char macro_name [NAMEBUFSIZE]; + + ACE_OS::memset (macro_name, + '\0', + NAMEBUFSIZE); + + const char *extension = ACE_OS::strrchr (fname, '.'); + + if (extension == 0) + { + // File seems to have no extension, so let us take the name + // as it is. + extension = fname; + } + + ACE_OS::sprintf (macro_name, prefix); + + size_t offset = ACE_OS::strlen (prefix); + + // Convert letters in fname to upper case. + for (int i = 0; i < (extension - fname); i++) + { + if (ACE_OS::ace_isalpha (fname [i])) + { + macro_name[i + offset] = (char) ACE_OS::ace_toupper (fname [i]); + } + else if (ACE_OS::ace_isdigit (fname [i])) + { + macro_name[i + offset] = fname[i]; + } + else + { + macro_name[i + offset] = '_'; + } + } + + ACE_OS::strcat (macro_name, suffix); + + // Generate the #ifndef ... #define statements. + this->print ("#ifndef %s\n", + macro_name); + this->print ("#define %s", + macro_name); +} + +TAO_OutStream & +TAO_OutStream::operator<< (const char *str) +{ + ACE_OS::fprintf (this->fp_, "%s", str); + ACE_OS::fflush (this->fp_); + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::UShort num) +{ + ACE_OS::fprintf (this->fp_, + "%hu", + num); + + ACE_OS::fflush (this->fp_); + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::Short num) +{ + ACE_OS::fprintf (this->fp_, + "%hd", + num); + + ACE_OS::fflush (this->fp_); + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::ULong num) +{ + ACE_OS::fprintf (this->fp_, + "%lu", + (unsigned long) num); + + ACE_OS::fflush (this->fp_); + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::Long num) +{ + ACE_OS::fprintf (this->fp_, + "%ld", + (long) num); + + ACE_OS::fflush (this->fp_); + + return *this; +} + +#if defined (ACE_WIN64) +TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::ULongLong num) +{ + ACE_OS::fprintf (this->fp_, + ACE_UINT64_FORMAT_SPECIFIER, + num); + + ACE_OS::fflush (this->fp_); + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::LongLong num) +{ + ACE_OS::fprintf (this->fp_, + ACE_INT64_FORMAT_SPECIFIER, + num); + + ACE_OS::fflush (this->fp_); + + return *this; +} +#endif /* ACE_WIN64 */ + +TAO_OutStream & +TAO_OutStream::operator<< (const unsigned long num) +{ + ACE_OS::fprintf (this->fp_, + "%lu", + num); + + ACE_OS::fflush (this->fp_); + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const long num) +{ + ACE_OS::fprintf (this->fp_, + "%ld", + num); + + ACE_OS::fflush (this->fp_); + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const TAO_NL&) +{ + ACE_OS::fprintf (this->fp_ , + "\n"); + this->indent (); + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const TAO_INDENT& i) +{ + this->incr_indent (0); + + if (i.do_now_) + { + this->nl (); + } + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const TAO_UNINDENT& i) +{ + this->decr_indent (0); + + if (i.do_now_) + { + this->nl (); + } + + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (Identifier *id) +{ + return this->print (id); +} + +TAO_OutStream & +TAO_OutStream::operator<< (AST_Expression *expr) +{ + return this->print (expr); +} diff --git a/modules/CIAO/tools/IDL3_to_IDL2/be_helper.h b/modules/CIAO/tools/IDL3_to_IDL2/be_helper.h new file mode 100644 index 00000000000..7fab4e04347 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/be_helper.h @@ -0,0 +1,180 @@ +/* -*- c++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO IDL +// +// = FILENAME +// be_helper.h +// +// = DESCRIPTION +// Defines the abstract class for outputting the C++ mapping. This is a +// helper class to the singleton TAO_CodeGen class +// +// = AUTHOR +// Aniruddha Gokhale +// +// Improvements by Carlos O'Ryan +// +// ============================================================================ + +#ifndef TAO_BE_OUTSTRM_H +#define TAO_BE_OUTSTRM_H + +#include "ace/CDR_Base.h" + +#include "TAO_IDL3_TO_IDL2_BE_Export.h" + +class Identifier; +class UTL_IdList; +class AST_Expression; + +// a dummy structure to inform TAO_OutStream's << operator to put a newline +// and use the current indentation for the succeeding line +struct TAO_IDL3_TO_IDL2_BE_Export TAO_NL +{ +public: + TAO_NL (void); +}; + +struct TAO_IDL3_TO_IDL2_BE_Export TAO_INDENT +{ + // = TITLE + // Operates like a manipulator, increasing the indentation level. + // + // = DESCRIPTION + // Increase the indentation level, if the "do_now" parameter is + // not zero then the <indent> method is called on the stream. + // + TAO_INDENT (int do_now = 0); + + const int do_now_; +}; + +struct TAO_IDL3_TO_IDL2_BE_Export TAO_UNINDENT +{ + // = TITLE + // Operates like a manipulator, decreasing the indentation level. + // + // = DESCRIPTION + // Decrease the indentation level, if the "do_now" parameter is + // not zero then the <indent> method is called on the stream. + // + TAO_UNINDENT (int do_now = 0); + + const int do_now_; +}; + +extern TAO_IDL3_TO_IDL2_BE_Export const TAO_NL be_nl; +extern TAO_IDL3_TO_IDL2_BE_Export const TAO_INDENT be_idt; +extern TAO_IDL3_TO_IDL2_BE_Export const TAO_INDENT be_idt_nl; +extern TAO_IDL3_TO_IDL2_BE_Export const TAO_UNINDENT be_uidt; +extern TAO_IDL3_TO_IDL2_BE_Export const TAO_UNINDENT be_uidt_nl; + +class TAO_IDL3_TO_IDL2_BE_Export TAO_OutStream +{ + // =TITLE + // TAO_OutStream + // + // =DESCRIPTION + // Defines an interface by which the backend code generator can + // print its output to the underlying I/O handle. This is a + // helper class that will be used by the TAO_CodeGen + // class. However, this is an abstract class and classes that + // understand specific front ends must derive from this class. +public: + TAO_OutStream (void); + // constructor. + + virtual ~TAO_OutStream (void); + // destructor. + + int open (const char *fname); + // open the underlying low-level handle for output. + + + FILE *file (void); + // Return the underlying lowlevel file pointer. + + int incr_indent (unsigned short flag = 1); + // increment the indentation level and by default actually indent the output + // accordingly + + int decr_indent (unsigned short flag = 1); + // decrease the indentation level and by default actually indent the output + // accordingly + + int reset (void); + // reset indentation level to 0 + + int indent (void); + // indent starting next line + + int nl (void); + // put a newline and indent on the next line + + int print (const char *format, ...); + // "printf" style variable argument print + + void gen_ifndef_string (const char *fname, + const char *prefix, + const char *suffix); + + // =overloaded operators + + TAO_OutStream &operator<< (const char *str); + // output the char string and return a reference to ourselves + + TAO_OutStream &operator<< (const ACE_CDR::UShort num); + // output the integer and return a reference to ourselves + + TAO_OutStream &operator<< (const ACE_CDR::Short num); + // output the integer and return a reference to ourselves + + TAO_OutStream &operator<< (const ACE_CDR::ULong num); + // output the integer and return a reference to ourselves + + TAO_OutStream &operator<< (const ACE_CDR::Long num); + // output the integer and return a reference to ourselves + +#if defined (ACE_WIN64) + TAO_OutStream &operator<< (const ACE_CDR::ULongLong num); + // output the integer and return a reference to ourselves + + TAO_OutStream &operator<< (const ACE_CDR::LongLong num); + // output the integer and return a reference to ourselves +#endif /* ACE_WIN64 */ + + TAO_OutStream &operator<< (const unsigned long num); + // output the integer and return a reference to ourselves + + TAO_OutStream &operator<< (const long num); + // output the integer and return a reference to ourselves + + // = MANIPULATORS + + TAO_OutStream &operator<< (const TAO_NL& nl); + TAO_OutStream &operator<< (const TAO_INDENT& i); + TAO_OutStream &operator<< (const TAO_UNINDENT& i); + + // The following will be provided by specialized classes. + + TAO_OutStream &operator<< (Identifier *id); + TAO_OutStream &operator<< (AST_Expression *expr); + + // Provided by specialized classes. + virtual TAO_OutStream &print (Identifier *id) = 0; + + virtual TAO_OutStream &print (AST_Expression *idl) = 0; + +protected: + FILE *fp_; + // The underlying low-level I/O handle. + + int indent_level_; + // indentation level +}; + +#endif // if !defined diff --git a/modules/CIAO/tools/IDL3_to_IDL2/be_init.cpp b/modules/CIAO/tools/IDL3_to_IDL2/be_init.cpp new file mode 100644 index 00000000000..fe111e60a47 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/be_init.cpp @@ -0,0 +1,32 @@ +// $Id$ + +#include "global_extern.h" +#include "be_extern.h" +#include "../../ciao/Version.h" + +TAO_IDL3_TO_IDL2_BE_Export void +BE_version (void) +{ + ACE_DEBUG ((LM_DEBUG, + "%s %s\n", + ACE_TEXT ("TAO_ID3_TO_IDL2_BE, version"), + ACE_TEXT (CIAO_VERSION))); +} + +TAO_IDL3_TO_IDL2_BE_Export int +BE_init (int & /* argc */, ACE_TCHAR * /*argv */ []) +{ + // Initialize BE global data object. + ACE_NEW_RETURN (be_global, + BE_GlobalData, + -1); + + idl_global->pass_orb_idl (true); + return 0; +} + +TAO_IDL3_TO_IDL2_BE_Export void +BE_post_init (char * /* files */ [], long /* nfiles */) +{ +} + diff --git a/modules/CIAO/tools/IDL3_to_IDL2/be_produce.cpp b/modules/CIAO/tools/IDL3_to_IDL2/be_produce.cpp new file mode 100644 index 00000000000..791be2e68ef --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/be_produce.cpp @@ -0,0 +1,171 @@ +// $Id$ + +/* + +COPYRIGHT + +Copyright 1992, 1993, 1994 Sun Microsystems, Inc. Printed in the United +States of America. All Rights Reserved. + +This product is protected by copyright and distributed under the following +license restricting its use. + +The Interface Definition Language Compiler Front End (CFE) is made +available for your use provided that you include this license and copyright +notice on all media and documentation and the software program in which +this product is incorporated in whole or part. You may copy and extend +functionality (but may not remove functionality) of the Interface +Definition Language CFE without charge, but you are not authorized to +license or distribute it to anyone else except as part of a product or +program developed by you or with the express written consent of Sun +Microsystems, Inc. ("Sun"). + +The names of Sun Microsystems, Inc. and any of its subsidiaries or +affiliates may not be used in advertising or publicity pertaining to +distribution of Interface Definition Language CFE as permitted herein. + +This license is effective until terminated by Sun for failure to comply +with this license. Upon termination, you shall destroy or return all code +and documentation for the Interface Definition Language CFE. + +INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED AS IS WITH NO WARRANTIES OF +ANY KIND INCLUDING THE WARRANTIES OF DESIGN, MERCHANTIBILITY AND FITNESS +FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR ARISING FROM A COURSE OF +DEALING, USAGE OR TRADE PRACTICE. + +INTERFACE DEFINITION LANGUAGE CFE IS PROVIDED WITH NO SUPPORT AND WITHOUT +ANY OBLIGATION ON THE PART OF Sun OR ANY OF ITS SUBSIDIARIES OR AFFILIATES +TO ASSIST IN ITS USE, CORRECTION, MODIFICATION OR ENHANCEMENT. + +SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES SHALL HAVE NO LIABILITY WITH +RESPECT TO THE INFRINGEMENT OF COPYRIGHTS, TRADE SECRETS OR ANY PATENTS BY +INTERFACE DEFINITION LANGUAGE CFE OR ANY PART THEREOF. + +IN NO EVENT WILL SUN OR ANY OF ITS SUBSIDIARIES OR AFFILIATES BE LIABLE FOR +ANY LOST REVENUE OR PROFITS OR OTHER SPECIAL, INDIRECT AND CONSEQUENTIAL +DAMAGES, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + +Use, duplication, or disclosure by the government is subject to +restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in +Technical Data and Computer Software clause at DFARS 252.227-7013 and FAR +52.227-19. + +Sun, Sun Microsystems and the Sun logo are trademarks or registered +trademarks of Sun Microsystems, Inc. + +SunSoft, Inc. +2550 Garcia Avenue +Mountain View, California 94043 + +NOTE: + +SunOS, SunSoft, Sun, Solaris, Sun Microsystems or the Sun logo are +trademarks or registered trademarks of Sun Microsystems, Inc. + + */ + +#include "TAO_IDL3_TO_IDL2_BE_Export.h" +#include "global_extern.h" +#include "be_extern.h" +#include "be_helper.h" +#include "fe_extern.h" +#include "utl_string.h" +#include "ast_root.h" +#include "checking_visitor.h" +#include "idl3_to_idl2_visitor.h" + +// Clean up before exit, whether successful or not. +TAO_IDL3_TO_IDL2_BE_Export void +BE_cleanup (void) +{ + idl_global->destroy (); +} + +// Abort this run of the BE. +TAO_IDL3_TO_IDL2_BE_Export void +BE_abort (void) +{ + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("Fatal Error - Aborting\n"))); + + // BE_cleanup will be called after the exception is caught. + throw Bailout (); +} + +// Do the work of this BE. This is the starting point for code generation. +TAO_IDL3_TO_IDL2_BE_Export void +BE_produce (void) +{ + // Get the root node. + AST_Decl *d = idl_global->root (); + AST_Root *ast_root = AST_Root::narrow_from_decl (d); + + if (ast_root == 0) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%N:%l) BE_produce - ") + ACE_TEXT ("No Root\n"))); + BE_abort (); + } + + checking_visitor c_visitor; + + if (be_global->encapsulate_idl2 ()) + { + if (c_visitor.visit_root (ast_root) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%N:%l) BE_produce - failed") + ACE_TEXT (" to accept checking visitor\n"))); + + BE_abort (); + } + } + + // Create and launch the 'equivalent IDL' visitor only if IDL3 + // declarations were seen by the checking visitor, or if we + // are not just including an IDL2-only original file in a new file. + if (c_visitor.is_idl3 () || !be_global->encapsulate_idl2 ()) + { + idl3_to_idl2_visitor visitor; + + if (visitor.visit_root (ast_root) == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%N:%l) BE_produce - failed to") + ACE_TEXT (" accept idl3_to_idl2 visitor\n"))); + } + } + else + { + TAO_OutStream *os = 0; + int status = be_global->outfile_init (os, + "", + "_IDL2.idl", + "_TAO_IDL_", + "_IDL_"); + + if (status == -1) + { + ACE_ERROR ((LM_ERROR, + ACE_TEXT ("(%N:%l) BE_produce - ") + ACE_TEXT ("failed to initialize output file\n"))); + + delete os; + os = 0; + BE_abort (); + } + + *os << be_nl << be_nl + << "#include \"" + << idl_global->stripped_filename ()->get_string () + << "\"" << be_nl << be_nl + << "#endif /* ifndef */" << be_nl; + + delete os; + os = 0; + } + + // Clean up. + BE_cleanup (); +} diff --git a/modules/CIAO/tools/IDL3_to_IDL2/be_sunsoft.cpp b/modules/CIAO/tools/IDL3_to_IDL2/be_sunsoft.cpp new file mode 100644 index 00000000000..e924ccea47d --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/be_sunsoft.cpp @@ -0,0 +1,157 @@ +// $Id$ + +#include "be_sunsoft.h" +#include "identifier_helper.h" + +#include "ast_expression.h" +#include "utl_identifier.h" +#include "utl_idlist.h" +#include "utl_string.h" + +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_ctype.h" + +ACE_RCSID (be, + be_sunsoft, + "$Id$") + +TAO_SunSoft_OutStream::TAO_SunSoft_OutStream (void) + : TAO_OutStream () +{ +} + +TAO_SunSoft_OutStream::~TAO_SunSoft_OutStream (void) +{ +} + +TAO_OutStream & +TAO_SunSoft_OutStream::print (Identifier *id) +{ + ACE_OS::fprintf (this->fp_, + id->get_string ()); + + return *this; +} + +TAO_OutStream& +TAO_SunSoft_OutStream::print (AST_Expression *expr) +{ + AST_Expression::AST_ExprValue *ev = expr->ev (); + + if (ev) + { + switch (ev->et) + { + case AST_Expression::EV_short: + this->TAO_OutStream::print (ACE_INT32_FORMAT_SPECIFIER_ASCII, ev->u.sval); + break; + case AST_Expression::EV_ushort: + this->TAO_OutStream::print (ACE_INT32_FORMAT_SPECIFIER_ASCII "%c", ev->u.usval, 'U'); + break; + case AST_Expression::EV_long: + this->TAO_OutStream::print (ACE_INT32_FORMAT_SPECIFIER_ASCII, ev->u.lval); + break; + case AST_Expression::EV_ulong: + this->TAO_OutStream::print (ACE_UINT32_FORMAT_SPECIFIER_ASCII "%c", ev->u.ulval, 'U'); + break; + // The ACE_LACKS_LONGLONG_T guards have been removed around + // the next 2 cases since the macros now used should work + // whether native 64-bit integers are defined or not. + case AST_Expression::EV_longlong: + this->TAO_OutStream::print ("ACE_INT64_LITERAL ("); + this->TAO_OutStream::print (ACE_INT64_FORMAT_SPECIFIER_ASCII, + ev->u.llval); + this->TAO_OutStream::print (")"); + break; + case AST_Expression::EV_ulonglong: + this->TAO_OutStream::print ("ACE_UINT64_LITERAL ("); + this->TAO_OutStream::print (ACE_UINT64_FORMAT_SPECIFIER_ASCII, + ev->u.ullval); + this->TAO_OutStream::print (")"); + break; + case AST_Expression::EV_float: + this->TAO_OutStream::print ("%f%c", ev->u.fval, 'F'); + break; + case AST_Expression::EV_double: + this->TAO_OutStream::print ("%24.16G", ev->u.dval); + break; + case AST_Expression::EV_longdouble: + break; + case AST_Expression::EV_char: + // isprint() sees \ and ' as printable characters + // so we have to test for them first. + if (ev->u.cval == '\\') + this->TAO_OutStream::print ("'\\\\'"); + else if (ev->u.cval == '\'') + this->TAO_OutStream::print ("'\\''"); + + // This handles hex and octal escape sequences + // that would print out either as weird characters + // or as an unsigned number too large for a char. + else if ((unsigned char) ev->u.cval > ACE_CHAR_MAX) + this->TAO_OutStream::print ("%hd", ev->u.cval); + else if (ACE_OS::ace_isprint (ev->u.cval)) + this->TAO_OutStream::print ("'%c'", ev->u.cval); + else if (ACE_OS::ace_iscntrl (ev->u.cval)) + switch (ev->u.cval) + { + case '\n': + this->TAO_OutStream::print ("'\\n'"); + break; + case '\t': + this->TAO_OutStream::print ("'\\t'"); + break; + case '\r': + this->TAO_OutStream::print ("'\\r'"); + break; + case '\v': + this->TAO_OutStream::print ("'\\v'"); + break; + case '\f': + this->TAO_OutStream::print ("'\\f'"); + break; + case '\b': + this->TAO_OutStream::print ("'\\b'"); + break; + case '\a': + this->TAO_OutStream::print ("'\\a'"); + break; + case '\?': + this->TAO_OutStream::print ("'?'"); + break; + default: + this->TAO_OutStream::print ("'\\x%x'", ev->u.cval); + } + else + this->TAO_OutStream::print ("'\\x%x'", ev->u.cval); + break; + case AST_Expression::EV_wchar: + this->TAO_OutStream::print ("L'%lc'", ev->u.wcval); + break; + case AST_Expression::EV_octet: + this->TAO_OutStream::print ("%d", ev->u.oval); + break; + case AST_Expression::EV_bool: + this->TAO_OutStream::print ("%s", ev->u.bval ? "true" : "false"); + break; + case AST_Expression::EV_string: + this->TAO_OutStream::print ("\"%s\"", ev->u.strval->get_string ()); + break; + case AST_Expression::EV_wstring: + this->TAO_OutStream::print ("L\"%s\"", ev->u.wstrval); + break; + case AST_Expression::EV_enum: + *this << IdentifierHelper::orig_sn (expr->n ()).c_str (); + break; + default: + break; + } + } + else + { + // XXXASG: need to add code here + } + + return *this; +} diff --git a/modules/CIAO/tools/IDL3_to_IDL2/be_sunsoft.h b/modules/CIAO/tools/IDL3_to_IDL2/be_sunsoft.h new file mode 100644 index 00000000000..c269c8c3bc8 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/be_sunsoft.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- */ +// $Id$ + +// ============================================================================ +// +// = LIBRARY +// TAO IDL +// +// = FILENAME +// be_sunsoft.h +// +// = DESCRIPTION +// SunSoft specific backend output generation +// +// = AUTHOR +// Aniruddha Gokhale +// +// ============================================================================ + +#ifndef TAO_BE_HELPER_H +#define TAO_BE_HELPER_H + +#include "be_helper.h" + +class TAO_IDL3_TO_IDL2_BE_Export TAO_SunSoft_OutStream : public TAO_OutStream +{ + // =TITLE + // TAO_SunSoft_OutStream + // =DESCRIPTION + // Backend specific to SunSoft AST nodes +public: + TAO_SunSoft_OutStream (void); + // constructor + + ~TAO_SunSoft_OutStream (void); + // destuctor + + virtual TAO_OutStream &print (Identifier *id); + // output the SunSoft IDL Identifier Node + + virtual TAO_OutStream &print (AST_Expression *expr); + // output the contents of the AST_Expression node +}; + +#endif // if !defined diff --git a/modules/CIAO/tools/IDL3_to_IDL2/checking_visitor.cpp b/modules/CIAO/tools/IDL3_to_IDL2/checking_visitor.cpp new file mode 100644 index 00000000000..2eef7370883 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/checking_visitor.cpp @@ -0,0 +1,355 @@ +/* -*- c++ -*- */ +// $Id$ + +#include "checking_visitor.h" +#include "identifier_helper.h" +#include "be_extern.h" + +#include "ast_component.h" +#include "ast_component_fwd.h" +#include "ast_eventtype.h" +#include "ast_eventtype_fwd.h" +#include "ast_home.h" +#include "ast_root.h" +#include "nr_extern.h" + +checking_visitor::checking_visitor (void) + : is_idl3_ (false), + is_local_idl3_ (false) +{ +} + +checking_visitor::~checking_visitor (void) +{ +} + +int +checking_visitor::visit_decl (AST_Decl *) +{ + return 0; +} + +int +checking_visitor::visit_scope (UTL_Scope *node) +{ + for (UTL_ScopeActiveIterator si (node, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + AST_Decl *d = si.item (); + AST_Decl::NodeType nt = d->node_type (); + + if (nt == AST_Decl::NT_typedef || nt == AST_Decl::NT_pre_defined) + { + continue; + } + + // Want to skip the uses_xxxConnection structs added by uses + // multiple ports. + // @@@ (JP) This will go away when the visitor is finished, since + // those uses_xxxConnection structs will not be added to the AST. + if (ScopeAsDecl (node)->node_type () == AST_Decl::NT_component + && nt != AST_Decl::NT_attr) + { + continue; + } + + if (d->ast_accept (this) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "checking_visitor::visit_scope - " + "codegen for scope failed\n"), + -1); + } + } + + return 0; +} + +int +checking_visitor::visit_type (AST_Type *) +{ + return 0; +} + +int +checking_visitor::visit_predefined_type (AST_PredefinedType *) +{ + return 0; +} + +int +checking_visitor::visit_module (AST_Module *node) +{ + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "checking_visitor::visit_module - " + "codegen for scope failed\n"), + -1); + } + + return 0; +} + +int +checking_visitor::visit_interface (AST_Interface *node) +{ + if (node->imported ()) + { + return 0; + } + + this->is_local_idl3_ = true; + return 0; +} + +int +checking_visitor::visit_interface_fwd (AST_InterfaceFwd *) +{ + return 0; +} + +int +checking_visitor::visit_valuebox (AST_ValueBox *) +{ + return 0; +} + +int +checking_visitor::visit_valuetype (AST_ValueType *) +{ + return 0; +} + +int +checking_visitor::visit_valuetype_fwd (AST_ValueTypeFwd *) +{ + return 0; +} + +int +checking_visitor::visit_component (AST_Component *node) +{ + this->is_idl3_ = true; + + if (node->imported ()) + { + return 0; + } + + this->is_local_idl3_ = true; + return 0; +} + +int +checking_visitor::visit_component_fwd (AST_ComponentFwd *node) +{ + this->is_idl3_ = true; + + if (node->imported ()) + { + return 0; + } + + this->is_local_idl3_ = true; + return 0; +} + +int +checking_visitor::visit_eventtype (AST_EventType *node) +{ + this->is_idl3_ = true; + + if (node->imported ()) + { + return 0; + } + + this->is_local_idl3_ = true; + return 0; +} + +int +checking_visitor::visit_eventtype_fwd (AST_EventTypeFwd *node) +{ + this->is_idl3_ = true; + + if (node->imported ()) + { + return 0; + } + + this->is_local_idl3_ = true; + return 0; +} + +int +checking_visitor::visit_home (AST_Home *node) +{ + this->is_idl3_ = true; + + if (node->imported ()) + { + return 0; + } + + this->is_local_idl3_ = true; + return 0; +} + + +int +checking_visitor::visit_factory (AST_Factory *) +{ + return 0; +} + +int +checking_visitor::visit_structure (AST_Structure *) +{ + return 0; +} + +int +checking_visitor::visit_structure_fwd (AST_StructureFwd *) +{ + return 0; +} + +int +checking_visitor::visit_exception (AST_Exception *) +{ + return 0; +} + +int +checking_visitor::visit_expression (AST_Expression *) +{ + return 0; +} + +int +checking_visitor::visit_enum (AST_Enum *) +{ + return 0; +} + + +int +checking_visitor::visit_union (AST_Union *) +{ + return 0; +} + +int +checking_visitor::visit_union_fwd (AST_UnionFwd *) +{ + return 0; +} + + +int +checking_visitor::visit_constant (AST_Constant *) +{ + return 0; +} + +int +checking_visitor::visit_enum_val (AST_EnumVal *) +{ + return 0; +} + +int +checking_visitor::visit_root (AST_Root *node) +{ + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "checking_visitor::visit_root - " + "codegen for scope failed\n"), + -1); + } + + return 0; +} + +int +checking_visitor::visit_native (AST_Native *) +{ + return 0; +} + +int +checking_visitor::visit_operation (AST_Operation *) +{ + return 0; +} + +int +checking_visitor::visit_field (AST_Field *) +{ + return 0; +} + +int +checking_visitor::visit_argument (AST_Argument *) +{ + return 0; +} + +int +checking_visitor::visit_attribute (AST_Attribute *) +{ + return 0; +} + +int +checking_visitor::visit_union_branch (AST_UnionBranch *) +{ + return 0; +} + +int +checking_visitor::visit_union_label (AST_UnionLabel *) +{ + return 0; +} + +int +checking_visitor::visit_array (AST_Array *) +{ + return 0; +} + +int +checking_visitor::visit_sequence (AST_Sequence *) +{ + return 0; +} + +int +checking_visitor::visit_string (AST_String *) +{ + return 0; +} + +int +checking_visitor::visit_typedef (AST_Typedef *) +{ + return 0; +} + +bool +checking_visitor::is_idl3 (void) const +{ + return this->is_idl3_; +} + +bool +checking_visitor::is_local_idl3 (void) const +{ + return this->is_local_idl3_; +} + diff --git a/modules/CIAO/tools/IDL3_to_IDL2/checking_visitor.h b/modules/CIAO/tools/IDL3_to_IDL2/checking_visitor.h new file mode 100644 index 00000000000..e5cb1147d1d --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/checking_visitor.h @@ -0,0 +1,94 @@ +// $Id$ + +/* -*- c++ -*- */ +// ============================================================================ +// +// = LIBRARY +// TAO_IDL3_TO_IDL2_BE_DLL +// +// = FILENAME +// checking_visitor.h +// +// = DESCRIPTION +// Visitor that checks input IDL3 in a separate pass. +// +// = AUTHOR +// Jeff Parsons <j.parsons@vanderbilt.edu> +// +// ============================================================================ + +#ifndef TAO_IDL_CHECKING_VISITOR_H +#define TAO_IDL_CHECKING_VISITOR_H + +#include "ast_visitor.h" +#include "utl_scoped_name.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "TAO_IDL3_TO_IDL2_BE_Export.h" + +class UTL_ExceptList; + +class TAO_IDL3_TO_IDL2_BE_Export checking_visitor : public ast_visitor +{ + // + // = TITLE + // checking_visitor. + // + // = DESCRIPTION + // Checks input IDL3 and sets flags used by subsequent + // equivalent IDL generating visitor. + // +public: + checking_visitor (void); + virtual ~checking_visitor (void); + + virtual int visit_decl (AST_Decl *d); + virtual int visit_scope (UTL_Scope *node); + virtual int visit_type (AST_Type *node); + virtual int visit_predefined_type (AST_PredefinedType *node); + virtual int visit_module (AST_Module *node); + virtual int visit_interface (AST_Interface *node); + virtual int visit_interface_fwd (AST_InterfaceFwd *node); + virtual int visit_valuebox (AST_ValueBox *node); + virtual int visit_valuetype (AST_ValueType *node); + virtual int visit_valuetype_fwd (AST_ValueTypeFwd *node); + virtual int visit_component (AST_Component *node); + virtual int visit_component_fwd (AST_ComponentFwd *node); + virtual int visit_eventtype (AST_EventType *node); + virtual int visit_eventtype_fwd (AST_EventTypeFwd *node); + virtual int visit_home (AST_Home *node); + virtual int visit_factory (AST_Factory *node); + virtual int visit_structure (AST_Structure *node); + virtual int visit_structure_fwd (AST_StructureFwd *node); + virtual int visit_exception (AST_Exception *node); + virtual int visit_expression (AST_Expression *node); + virtual int visit_enum (AST_Enum *node); + virtual int visit_operation (AST_Operation *node); + virtual int visit_field (AST_Field *node); + virtual int visit_argument (AST_Argument *node); + virtual int visit_attribute (AST_Attribute *node); + virtual int visit_union (AST_Union *node); + virtual int visit_union_fwd (AST_UnionFwd *node); + virtual int visit_union_branch (AST_UnionBranch *node); + virtual int visit_union_label (AST_UnionLabel *node); + virtual int visit_constant (AST_Constant *node); + virtual int visit_enum_val (AST_EnumVal *node); + virtual int visit_array (AST_Array *node); + virtual int visit_sequence (AST_Sequence *node); + virtual int visit_string (AST_String *node); + virtual int visit_typedef (AST_Typedef *node); + virtual int visit_root (AST_Root *node); + virtual int visit_native (AST_Native *node); + + bool is_idl3 (void) const; + bool is_local_idl3 (void) const; + +private: + bool is_idl3_; + bool is_local_idl3_; +}; + +#endif /* TAO_IDL_CHECKING_VISITOR_H */ diff --git a/modules/CIAO/tools/IDL3_to_IDL2/identifier_helper.cpp b/modules/CIAO/tools/IDL3_to_IDL2/identifier_helper.cpp new file mode 100644 index 00000000000..9b8a255b9c5 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/identifier_helper.cpp @@ -0,0 +1,123 @@ +/* -*- c++ -*- */ +// $Id$ + +#include "identifier_helper.h" +#include "utl_identifier.h" +#include "utl_string.h" +#include "fe_private.h" +#include "global_extern.h" + +Identifier * +IdentifierHelper::original_local_name (Identifier * local_name) +{ + Identifier * id = 0; + const char *lname = local_name->get_string (); + + // Remove _cxx_ if: + // 1. it occurs and + // 2. it occurs at the beginning of the string and + // 3. the rest of the string is a C++ keyword + if (ACE_OS::strstr (lname, "_cxx_") == lname) + { + TAO_IDL_CPP_Keyword_Table cpp_key_tbl; + + unsigned int len = + static_cast<unsigned int> (ACE_OS::strlen (lname + 5)); + + const TAO_IDL_CPP_Keyword_Entry *entry = + cpp_key_tbl.lookup (lname + 5, len); + + if (entry != 0) + { + // Remove _cxx_ and assign to the Identifier variable. + ACE_NEW_RETURN (id, + Identifier (lname + 5), + 0); + } + } + + if (id == 0) + { + id = local_name->copy (); + } + + return id; +} + +ACE_CString +IdentifierHelper::orig_sn (UTL_IdList * sn, bool appended_to) +{ + ACE_CString retval; + bool first = true; + bool second = false; + Identifier *id = 0; + + for (UTL_IdListActiveIterator i (sn); !i.is_done ();) + { + if (!first) + { + retval += "::"; + } + else if (second) + { + first = second = false; + } + + id = IdentifierHelper::original_local_name (i.item ()); + i.next (); + + // Append the identifier. + retval += + appended_to && i.is_done () + ? id->get_string () + : IdentifierHelper::try_escape (id).c_str (); + + if (first) + { + if (ACE_OS::strcmp (id->get_string (), "") != 0) + { + // Does not start with a "". + first = false; + } + else + { + second = true; + } + } + + id->destroy (); + delete id; + id = 0; + } + + return retval; +} + +bool +IdentifierHelper::is_idl_keyword (Identifier * local_name) +{ + UTL_String utl_tmp (local_name->get_string ()); + ACE_CString ext_id (utl_tmp.get_canonical_rep (), + 0, + false); + + int status = idl_global->idl_keywords ().find (ext_id); + utl_tmp.destroy (); + + return status == 0; +} + +ACE_CString +IdentifierHelper::try_escape (Identifier * local_name) +{ + ACE_CString s_local_name (local_name->get_string ()); + + if (IdentifierHelper::is_idl_keyword (local_name)) + { + return "_" + s_local_name; + } + else + { + return s_local_name; + } +} diff --git a/modules/CIAO/tools/IDL3_to_IDL2/identifier_helper.h b/modules/CIAO/tools/IDL3_to_IDL2/identifier_helper.h new file mode 100644 index 00000000000..a6a6fcc88df --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/identifier_helper.h @@ -0,0 +1,66 @@ +// $Id$ + +/* -*- c++ -*- */ +// ============================================================================ +// +// = LIBRARY +// TAO_IDL3_TO_IDL2_BE_DLL +// +// = FILENAME +// identifier_helper.h +// +// = DESCRIPTION +// Utilities associated with UTL_Identifier. +// +// = AUTHOR +// Jeff Parsons <j.parsons@vanderbilt.edu> +// +// ============================================================================ + +#ifndef IDENTIFIER_HELPER_H +#define IDENTIFIER_HELPER_H + +#include "utl_scoped_name.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "TAO_IDL3_TO_IDL2_BE_Export.h" +#include "ace/SString.h" + +class Identifier; + +struct TAO_IDL3_TO_IDL2_BE_Export IdentifierHelper +{ + // + // = TITLE + // IdentifierHelper. + // + // = DESCRIPTION + // 1) keeps escape (leading underscore character in generated + // identifier in IDL + // 2) removes the '_' escape character when the identifier is + // part of another identifier such as in provides_XXX + // 3) removes any '_cxx_' in generated IDL + + static Identifier * + original_local_name (Identifier * local_name); + + // Removes '_cxx_ from segments of a scoped name, and optionally + // de-escape the last segment, if it's to be appended to. + static ACE_CString + orig_sn (UTL_ScopedName * scoped_name, bool appended_to = false); + + // Detects case-insensitive match with IDL keyword. + static bool + is_idl_keyword (Identifier * local_name); + + // Preserves the 'escape' (leading underscore) in a + // generated identifier if necessary. + static ACE_CString + try_escape (Identifier * local_name); +}; + +#endif /* IDENTIFIER_HELPER_H */ + diff --git a/modules/CIAO/tools/IDL3_to_IDL2/idl3_to_idl2_visitor.cpp b/modules/CIAO/tools/IDL3_to_IDL2/idl3_to_idl2_visitor.cpp new file mode 100644 index 00000000000..d443365a105 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/idl3_to_idl2_visitor.cpp @@ -0,0 +1,774 @@ +/* -*- c++ -*- */ +// $Id$ + +#include "idl3_to_idl2_visitor.h" +#include "identifier_helper.h" +#include "be_sunsoft.h" +#include "be_extern.h" + +#include "ast_component_fwd.h" +#include "ast_eventtype.h" +#include "ast_eventtype_fwd.h" +#include "ast_home.h" +#include "ast_operation.h" +#include "ast_root.h" +#include "utl_exceptlist.h" +#include "utl_identifier.h" +#include "global_extern.h" +#include "nr_extern.h" + +idl3_to_idl2_visitor::idl3_to_idl2_visitor (void) + : basic_visitor () +{ +} + +idl3_to_idl2_visitor::~idl3_to_idl2_visitor (void) +{ +} + +int +idl3_to_idl2_visitor::visit_module (AST_Module *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl; + + ACE_CString name = + IdentifierHelper::try_escape (node->original_local_name ()); + + *os << "module " << name.c_str () << be_nl + << "{" << be_idt; + + this->check_id_and_version (node); + this->check_prefix (node); + + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "idl3_to_idl2_visitor::visit_module - " + "codegen for scope failed\n"), + -1); + } + + *os << be_uidt_nl + << "}; // end of module " << name.c_str (); + + return 0; +} + +int +idl3_to_idl2_visitor::visit_interface (AST_Interface *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl; + + if (node->is_local ()) + { + *os << "local "; + } + + if (node->is_abstract ()) + { + *os << "abstract "; + } + + *os << "interface " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str (); + + AST_Interface **parents = node->inherits (); + + for (long i = 0; i < node->n_inherits (); ++i) + { + if (i == 0) + { + *os << " : "; + } + else + { + *os << ", "; + } + + *os << IdentifierHelper::orig_sn (parents[i]->name ()).c_str (); + } + + *os << be_nl + << "{" << be_idt; + + this->check_id_and_version (node); + this->check_prefix (node); + + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "idl3_to_idl2_visitor::visit_interface - " + "codegen for scope failed\n"), + -1); + } + + *os << be_uidt_nl + << "};"; + + return 0; +} + +int +idl3_to_idl2_visitor::visit_component (AST_Component *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl + << "interface " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str (); + + AST_Component *base = node->base_component (); + long nsupports = node->n_supports (); + + *os << " : " + << (base != 0 + ? IdentifierHelper::orig_sn (base->name ()).c_str () + : "Components::CCMObject"); + + for (long i = 0; i < nsupports; ++i) + { + *os << ", " + << IdentifierHelper::orig_sn (node->supports ()[i]->name ()).c_str (); + } + + *os << be_nl + << "{" << be_idt; + + this->check_id_and_version (node); + + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "idl3_to_idl2_visitor::visit_component - " + "codegen for scope failed\n"), + -1); + } + + this->gen_provides (node); + this->gen_uses (node); + this->gen_publishes (node); + this->gen_emits (node); + this->gen_consumes (node); + + *os << be_uidt_nl + << "};"; + + return 0; +} + +int +idl3_to_idl2_visitor::visit_component_fwd (AST_ComponentFwd *node) +{ + if (node->imported ()) + { + return 0; + } + + *os << be_nl << be_nl + << "component " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str () + << ";"; + + return 0; +} + +int +idl3_to_idl2_visitor::visit_eventtype (AST_EventType *node) +{ + if (node->imported ()) + { + return 0; + } + + if (this->visit_valuetype (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "idl3_to_idl2_visitor::visit_eventtype - " + "codegen for valuetype failed\n"), + -1); + } + + *os << be_nl << be_nl + << "interface " << node->original_local_name () << "Consumer : "; + + AST_Interface *parent = 0; + AST_Decl::NodeType nt = AST_Decl::NT_native; + + if (node->n_inherits () > 0) + { + parent = node->inherits ()[0]; + AST_Type *ut = parent->unaliased_type (); + nt = ut->node_type (); + } + + if (node->n_inherits () == 0 || nt == AST_Decl::NT_valuetype) + { + *os << "Components::EventConsumerBase"; + } + else + { + *os << IdentifierHelper::orig_sn (node->inherits ()[0]->name (), true).c_str () + << "Consumer"; + } + + *os << be_nl + << "{" << be_idt_nl + << "void push_" << node->original_local_name () << " (in " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str () + << " the_" + << node->original_local_name () << ");" << be_uidt_nl + << "};"; + + return 0; +} + +int +idl3_to_idl2_visitor::visit_eventtype_fwd (AST_EventTypeFwd *node) +{ + if (node->imported ()) + { + return 0; + } + + if (this->visit_valuetype_fwd (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "idl3_to_idl2_visitor::visit_eventtype_fwd - " + "codegen for valuetype_fwd failed\n"), + -1); + } + + *os << be_nl + << "interface " << node->original_local_name () << "Consumer;"; + + return 0; +} + +int +idl3_to_idl2_visitor::visit_home (AST_Home *node) +{ + if (node->imported ()) + { + return 0; + } + + ACE_CString explicit_name = node->original_local_name ()->get_string (); + explicit_name += "Explicit"; + + *os << be_nl << be_nl + << "interface " << explicit_name.c_str () << " : "; + + AST_Home *base = node->base_home (); + + if (base == 0) + { + *os << "Components::CCMHome"; + } + else + { + *os << IdentifierHelper::orig_sn (base->name (), true).c_str () + << "Explicit"; + } + + *os << be_nl + << "{" << be_idt; + + this->check_id_and_version (node); + + // Create a temporary interface node corresponding to the one we + // just generated above for the home explicit interface. + UTL_ScopedName *sn = + this->create_scoped_name (0, + explicit_name.c_str (), + 0, + ScopeAsDecl (node->defined_in ())); + + AST_Interface xplicit (sn, + 0, + 0, + 0, + 0, + false, + false); + xplicit.set_defined_in (node->defined_in ()); + + // Reset the home's decls to be defined in the explicit home interface. + this->tranfer_scope_elements (node, xplicit); + + this->gen_factories (node, xplicit); + this->gen_finders (node, xplicit); + + *os << be_uidt_nl + << "};" << be_nl << be_nl; + + xplicit.destroy (); + sn->destroy (); + delete sn; + sn = 0; + + AST_ValueType *key = node->primary_key (); + ACE_CString mng_name = + IdentifierHelper::orig_sn (node->managed_component ()->name ()); + ACE_CString key_name; + + // Generate the implicit home interface and its operations. + *os << "interface " << node->original_local_name () << "Implicit" + << (key == 0 ? " : Components::KeylessCCMHome" : "") << be_nl + << "{" << be_idt_nl + << mng_name.c_str () << " create ("; + + if (key != 0) + { + key_name = + IdentifierHelper::orig_sn (key->name ()); + + *os << "in " << key_name.c_str () << " key"; + } + + *os << ")" << be_idt_nl + << "raises (Components::CreateFailure"; + + if (key != 0) + { + *os << ", Components::InvalidKey, Components::DuplicateKeyValue"; + } + + *os << ");" << be_uidt; + + if (key != 0) + { + *os << be_nl << be_nl + << mng_name.c_str () + << " find_by_primary_key (in " << key_name.c_str () + << " key)" << be_idt_nl + << "raises (Components::InvalidKey, Components::UnknownKeyValue, " + << "Components::FinderFailure);" << be_uidt; + + *os << be_nl << be_nl + << "void remove (in " << key_name.c_str () << " key)" << be_idt_nl + << "raises (Components::InvalidKey, Components::UnknownKeyValue, " + << "Components::RemoveFailure);" << be_uidt; + + *os << be_nl << be_nl + << key_name.c_str () << " get_primary_key (in " + << mng_name.c_str () << " comp);"; + } + + *os << be_uidt_nl + << "};"; + + // Create equivalent interface. + *os << be_nl << be_nl + << "interface " + << IdentifierHelper::try_escape (node->original_local_name ()).c_str () + << " : " + << node->original_local_name () << "Explicit, " + << node->original_local_name () << "Implicit" << be_nl + << "{" << be_nl + << "};"; + + return 0; +} + +int +idl3_to_idl2_visitor::visit_root (AST_Root *node) +{ + int status = be_global->outfile_init (this->os, + "", + "_IDL2.idl", + "_TAO_IDL_", + "_IDL_"); + + if (status == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("idl3_to_idl2_visitor::visit_root - ") + ACE_TEXT ("failed to initialize output file\n")), + -1); + } + + ACE_CString filename; + + for (size_t i = 0; i < idl_global->n_included_idl_files (); ++i) + { + if (i == 0) + { + *os << be_nl; + } + + ACE_CString raw_filename = idl_global->included_idl_files ()[i]; + bool excluded_file_found = + this->match_excluded_file (raw_filename.c_str ()); + + if (raw_filename.find (".pidl") != ACE_CString::npos + || raw_filename == "orb.idl" + || raw_filename == "Components.idl" + || excluded_file_found) + { + filename = raw_filename; + } + else + { + filename = + raw_filename.substr (0, raw_filename.rfind ('.')) + "_IDL2.idl"; + } + + *os << be_nl + << "#include \"" << filename.c_str () << "\""; + } + + const char *pfix = node->prefix (); + + if (ACE_OS::strcmp (pfix, "") != 0) + { + *os << be_nl << be_nl + << "#pragma prefix \"" << pfix << "\""; + } + + if (this->visit_scope (node) != 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("idl3_to_idl2_visitor::visit_root - ") + ACE_TEXT ("codegen for scope failed\n")), + -1); + } + + *os << be_nl << be_nl + << "#endif /* ifndef */" << be_nl << be_nl; + + return 0; +} + +void +idl3_to_idl2_visitor::gen_provides (AST_Component *node) +{ + ACE_Unbounded_Queue<AST_Component::port_description> &s = + node->provides (); + AST_Component::port_description *pd = 0; + + for (ACE_Unbounded_Queue_Iterator<AST_Component::port_description> iter (s); + ! iter.done (); + iter.advance ()) + { + iter.next (pd); + + Identifier *orig_id = IdentifierHelper::original_local_name (pd->id); + + *os << be_nl << be_nl + << IdentifierHelper::orig_sn (pd->impl->name ()).c_str () + << " provide_" << orig_id << " ();"; + + orig_id->destroy (); + delete orig_id; + orig_id = 0; + } +} + +void +idl3_to_idl2_visitor::gen_uses (AST_Component *node) +{ + ACE_Unbounded_Queue<AST_Component::port_description> &s = + node->uses (); + AST_Component::port_description *pd = 0; + + for (ACE_Unbounded_Queue_Iterator<AST_Component::port_description> iter (s); + ! iter.done (); + iter.advance ()) + { + iter.next (pd); + + *os << be_nl << be_nl; + + Identifier *orig_id = IdentifierHelper::original_local_name (pd->id); + + if (pd->is_multiple) + { + *os << "struct " << orig_id << "Connection" << be_nl + << "{" << be_idt_nl + << IdentifierHelper::orig_sn (pd->impl->name ()).c_str () + << " objref;" << be_nl + << "Components::Cookie ck;" << be_uidt_nl + << "};" << be_nl << be_nl + << "typedef sequence<" << orig_id << "Connection> " + << orig_id << "Connections;" + << be_nl << be_nl + << "Components::Cookie connect_" << orig_id << " (in " + << IdentifierHelper::orig_sn (pd->impl->name ()).c_str () + << " connection)" << be_idt_nl + << "raises (Components::ExceededConnectionLimit, " + << "Components::InvalidConnection);" << be_uidt_nl << be_nl + << IdentifierHelper::orig_sn (pd->impl->name ()).c_str () + << " disconnect_" << orig_id + << " (in Components::Cookie ck)" << be_idt_nl + << "raises (Components::InvalidConnection);" + << be_uidt_nl << be_nl + << orig_id << "Connections get_connections_" << orig_id + << " ();"; + } + else + { + *os << "void connect_" << orig_id << " (in " + << IdentifierHelper::orig_sn (pd->impl->name ()).c_str () + << " conxn)" << be_idt_nl + << "raises (Components::AlreadyConnected, " + << "Components::InvalidConnection);" << be_uidt_nl << be_nl + << IdentifierHelper::orig_sn (pd->impl->name ()).c_str () + << " disconnect_" << orig_id + << " ()" << be_idt_nl + << "raises (Components::NoConnection);" << be_uidt_nl << be_nl + << IdentifierHelper::orig_sn (pd->impl->name ()).c_str () + << " get_connection_" << orig_id + << " ();"; + } + + orig_id->destroy (); + delete orig_id; + orig_id = 0; + } +} + +void +idl3_to_idl2_visitor::gen_publishes (AST_Component *node) +{ + ACE_Unbounded_Queue<AST_Component::port_description> &s = + node->publishes (); + AST_Component::port_description *pd = 0; + + for (ACE_Unbounded_Queue_Iterator<AST_Component::port_description> iter (s); + ! iter.done (); + iter.advance ()) + { + iter.next (pd); + + Identifier *orig_id = IdentifierHelper::original_local_name (pd->id); + + *os << be_nl << be_nl + << "Components::Cookie subscribe_" << orig_id + << " (in " + << IdentifierHelper::orig_sn (pd->impl->name (), true).c_str () + << "Consumer consumer)" + << be_idt_nl + << "raises (Components::ExceededConnectionLimit);" + << be_uidt_nl << be_nl + << IdentifierHelper::orig_sn (pd->impl->name (), true).c_str () + << "Consumer unsubscribe_" << orig_id + << " (in Components::Cookie ck)" << be_idt_nl + << "raises (Components::InvalidConnection);" << be_uidt; + + orig_id->destroy (); + delete orig_id; + orig_id = 0; + } +} + +void +idl3_to_idl2_visitor::gen_emits (AST_Component *node) +{ + ACE_Unbounded_Queue<AST_Component::port_description> &s = + node->emits (); + AST_Component::port_description *pd = 0; + + for (ACE_Unbounded_Queue_Iterator<AST_Component::port_description> iter (s); + ! iter.done (); + iter.advance ()) + { + iter.next (pd); + + Identifier *orig_id = IdentifierHelper::original_local_name (pd->id); + + *os << be_nl << be_nl + << "void connect_" << orig_id + << " (in " + << IdentifierHelper::orig_sn (pd->impl->name (), true).c_str () + << "Consumer consumer)" << be_idt_nl + << "raises (Components::AlreadyConnected);" + << be_uidt_nl << be_nl + << IdentifierHelper::orig_sn (pd->impl->name (), true).c_str () + << "Consumer disconnect_" << orig_id + << " ()" << be_idt_nl + << "raises (Components::NoConnection);" << be_uidt; + + orig_id->destroy (); + delete orig_id; + orig_id = 0; + } +} + +void +idl3_to_idl2_visitor::gen_consumes (AST_Component *node) +{ + ACE_Unbounded_Queue<AST_Component::port_description> &s = + node->consumes (); + AST_Component::port_description *pd = 0; + + for (ACE_Unbounded_Queue_Iterator<AST_Component::port_description> iter (s); + ! iter.done (); + iter.advance ()) + { + iter.next (pd); + + Identifier *orig_id = IdentifierHelper::original_local_name (pd->id); + + *os << be_nl << be_nl + << IdentifierHelper::orig_sn (pd->impl->name (), true).c_str () + << "Consumer get_consumer_" << orig_id + << " ();"; + + orig_id->destroy (); + delete orig_id; + orig_id = 0; + } +} + +UTL_ScopedName * +idl3_to_idl2_visitor::create_scoped_name (const char *prefix, + const char *local_name, + const char *suffix, + AST_Decl *parent) +{ + ACE_CString local_string (prefix, + 0, + false); + local_string += local_name; + local_string += suffix; + Identifier *local_id = 0; + ACE_NEW_RETURN (local_id, + Identifier (local_string.fast_rep ()), + 0); + UTL_ScopedName *last_segment = 0; + ACE_NEW_RETURN (last_segment, + UTL_ScopedName (local_id, + 0), + 0); + UTL_ScopedName *full_name = + static_cast<UTL_ScopedName *> (parent->name ()->copy ()); + full_name->nconc (last_segment); + return full_name; +} + +void +idl3_to_idl2_visitor::tranfer_scope_elements (AST_Home *src, + AST_Interface &dst) +{ + // Transfer the elements of the home's scope to the temporary + // explicit home interface. + for (UTL_ScopeActiveIterator src_iter (src, UTL_Scope::IK_decls); + ! src_iter.is_done (); + src_iter.next ()) + { + AST_Decl *d = src_iter.item (); + d->set_defined_in (&dst); + UTL_ScopedName *new_name = + this->create_scoped_name (0, + d->local_name ()->get_string (), + 0, + &dst); + d->set_name (new_name); + dst.add_to_scope (d); + } + + // Visit the transferred scope elements normally to generate the IDL. + // This way referenced items will have the interface's name in the + // scoped name instead of the home's name. + for (UTL_ScopeActiveIterator dst_iter (&dst, UTL_Scope::IK_decls); + ! dst_iter.is_done (); + dst_iter.next ()) + { + if (dst_iter.item ()->ast_accept (this) != 0) + { + ACE_ERROR ((LM_ERROR, + "idl3_to_idl2_visitor::tranfer_scope_elements - " + "codegen for destination scope failed\n")); + } + } +} + +void +idl3_to_idl2_visitor::gen_factories (AST_Home *node, + AST_Interface &) +{ + AST_Operation **item = 0; + + for (ACE_Unbounded_Queue_Iterator<AST_Operation *> i (node->factories ()); + ! i.done (); + i.advance ()) + { + i.next (item); + + *os << be_nl << be_nl + << IdentifierHelper::orig_sn (node->managed_component ()->name ()).c_str () + << " " + << IdentifierHelper::try_escape ((*item)->original_local_name ()).c_str () + << " ("; + + this->gen_params (*item, (*item)->argument_count ()); + + *os << ")"; + + UTL_ExceptList *exceps = (*item)->exceptions (); + + if (exceps != 0 && exceps->length () > 0) + { + this->gen_exception_list (exceps, "", false); + } + else + { + *os << be_idt_nl + << "raises ("; + } + + *os << "Components::CreateFailure);" << be_uidt; + } +} + +void +idl3_to_idl2_visitor::gen_finders (AST_Home *node, + AST_Interface &) +{ + AST_Operation **item = 0; + + for (ACE_Unbounded_Queue_Iterator<AST_Operation *> i (node->finders ()); + ! i.done (); + i.advance ()) + { + i.next (item); + + *os << be_nl << be_nl + << IdentifierHelper::orig_sn (node->managed_component ()->name ()).c_str () + << " " + << IdentifierHelper::try_escape( (*item)->original_local_name ()).c_str () + << " ("; + + this->gen_params (*item, (*item)->argument_count ()); + + *os << ")"; + + UTL_ExceptList *exceps = (*item)->exceptions (); + + if (exceps != 0 && exceps->length () > 0) + { + this->gen_exception_list (exceps, "", false); + } + else + { + *os << be_idt_nl + << "raises ("; + } + + *os << "Components::FinderFailure);" << be_uidt; + } +} + diff --git a/modules/CIAO/tools/IDL3_to_IDL2/idl3_to_idl2_visitor.h b/modules/CIAO/tools/IDL3_to_IDL2/idl3_to_idl2_visitor.h new file mode 100644 index 00000000000..3880690a461 --- /dev/null +++ b/modules/CIAO/tools/IDL3_to_IDL2/idl3_to_idl2_visitor.h @@ -0,0 +1,71 @@ +// $Id$ + +/* -*- c++ -*- */ +// ============================================================================ +// +// = LIBRARY +// TAO_IDL3_TO_IDL2_BE_DLL +// +// = FILENAME +// idl3_to_idl2_visitor.h +// +// = DESCRIPTION +// Generates equivalent IDL2 from IDL3. +// +// = AUTHOR +// Jeff Parsons <j.parsons@vanderbilt.edu> +// +// ============================================================================ + +#ifndef TAO_IDL3_TO_IDL2_VISITOR_H +#define TAO_IDL3_TO_IDL2_VISITOR_H + +#include "basic_visitor.h" +#include "utl_scoped_name.h" + +#if !defined (ACE_LACKS_PRAGMA_ONCE) +# pragma once +#endif /* ACE_LACKS_PRAGMA_ONCE */ + +#include "TAO_IDL3_TO_IDL2_BE_Export.h" + +class TAO_IDL3_TO_IDL2_BE_Export idl3_to_idl2_visitor : public basic_visitor +{ + // + // = TITLE + // idl3_to_idl2_visitor. + // + // = DESCRIPTION + // IDL3 to IDL2 conversion visitor. The methods are + // not pure virtual to facilitate the implementation of some + // derived visitors that override only a few. + // +public: + idl3_to_idl2_visitor (void); + virtual ~idl3_to_idl2_visitor (void); + + virtual int visit_module (AST_Module *node); + virtual int visit_interface (AST_Interface *node); + virtual int visit_component (AST_Component *node); + virtual int visit_component_fwd (AST_ComponentFwd *node); + virtual int visit_eventtype (AST_EventType *node); + virtual int visit_eventtype_fwd (AST_EventTypeFwd *node); + virtual int visit_home (AST_Home *node); + virtual int visit_root (AST_Root *node); + +private: + void gen_provides (AST_Component *node); + void gen_uses (AST_Component *node); + void gen_publishes (AST_Component *node); + void gen_emits (AST_Component *node); + void gen_consumes (AST_Component *node); + UTL_ScopedName *create_scoped_name (const char *prefix, + const char *local_name, + const char *suffix, + AST_Decl *parent); + void tranfer_scope_elements (AST_Home *src, AST_Interface &dst); + void gen_factories (AST_Home *node, AST_Interface &xplicit); + void gen_finders (AST_Home *node, AST_Interface &xplicit); +}; + +#endif /* TAO_IDL3_TO_IDL2_VISITOR_H */ |