diff options
author | William R. Otte <wotte@dre.vanderbilt.edu> | 2006-07-24 15:50:21 +0000 |
---|---|---|
committer | William R. Otte <wotte@dre.vanderbilt.edu> | 2006-07-24 15:50:21 +0000 |
commit | 3aff90f4a822fcf5d902bbfbcc9fa931d6191a8c (patch) | |
tree | 197c810e5f5bce17b1233a7cb8d7b50c0bcd25e2 /TAO/TAO_IDL/ast | |
parent | 6b846cf03c0bcbd8c276cb0af61a181e5f98eaae (diff) | |
download | ATCD-3aff90f4a822fcf5d902bbfbcc9fa931d6191a8c.tar.gz |
Repo restructuring
Diffstat (limited to 'TAO/TAO_IDL/ast')
42 files changed, 18986 insertions, 0 deletions
diff --git a/TAO/TAO_IDL/ast/ast_argument.cpp b/TAO/TAO_IDL/ast/ast_argument.cpp new file mode 100644 index 00000000000..0847850d552 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_argument.cpp @@ -0,0 +1,153 @@ +// $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. + +*/ + +// AST_Argument nodes denote arguments to an operation. They +// are AST_Fields with directions. Thus, they have a name +// (an UTL_ScopedName) and a type (a subclass of AST_Type). +// Additionally they have a direction field which takes values +// from the enum AST_Argument::Direction. + +#include "ast_argument.h" +#include "ast_visitor.h" + +ACE_RCSID (ast, + ast_argument, + "$Id$") + +// Static functions. + +// Convert an enum Direction value to a char *. +static const char * +direction_to_string (AST_Argument::Direction d) +{ + switch (d) + { + case AST_Argument::dir_IN: + return "in"; + case AST_Argument::dir_OUT: + return "out"; + case AST_Argument::dir_INOUT: + return "inout"; + } + + return 0; +} + +AST_Argument::AST_Argument (void) + : COMMON_Base (), + AST_Decl (), + AST_Field (), + pd_direction (dir_IN) +{ +} + +AST_Argument::AST_Argument (Direction d, + AST_Type *ft, + UTL_ScopedName *n) + : COMMON_Base (), + AST_Decl (AST_Decl::NT_argument, + n), + AST_Field (AST_Decl::NT_argument, + ft, + n), + pd_direction (d) +{ +} + +AST_Argument::~AST_Argument (void) +{ +} + +// Dump this AST_Argument node to the ostream o. +void +AST_Argument::dump (ACE_OSTREAM_TYPE &o) +{ + this->dump_i (o, direction_to_string (pd_direction)); + this->dump_i (o, " "); + AST_Field::dump (o); +} + +int +AST_Argument::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_argument (this); +} + +void +AST_Argument::destroy (void) +{ + this->AST_Field::destroy (); +} + +AST_Argument::Direction +AST_Argument::direction (void) +{ + return this->pd_direction; +} + +// Narrowing operations. +IMPL_NARROW_METHODS1(AST_Argument, AST_Field) +IMPL_NARROW_FROM_DECL(AST_Argument) diff --git a/TAO/TAO_IDL/ast/ast_array.cpp b/TAO/TAO_IDL/ast/ast_array.cpp new file mode 100644 index 00000000000..9f602b8633a --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_array.cpp @@ -0,0 +1,283 @@ +// $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. + +*/ + +// AST_Array nodes denote array type and field modifiers. +// AST_Array nodes have a list of dimensions (a UTL_ExprList) +// a count of the number of dimensions and a base type (a +// subtype of AST_ConcreteType. This means that we cannot have +// arrays of AST_Interfaces??? + +#include "ast_array.h" +#include "ast_expression.h" +#include "ast_visitor.h" +#include "utl_exprlist.h" +#include "utl_identifier.h" +#include "ace/Log_Msg.h" +#include "ace/OS_Memory.h" + +ACE_RCSID (ast, + ast_array, + "$Id$") + +// Constructor(s) and destructor. + +AST_Array::AST_Array (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + AST_ConcreteType (), + pd_n_dims (0), + pd_dims (0), + pd_base_type (0), + owns_base_type_ (false) +{ +} + +AST_Array::AST_Array (UTL_ScopedName *n, + unsigned long nd, + UTL_ExprList *ds, + bool local, + bool abstract) + : COMMON_Base (local, + abstract), + AST_Decl (AST_Decl::NT_array, + n, + true), + AST_Type (AST_Decl::NT_array, + n), + AST_ConcreteType (AST_Decl::NT_array, + n), + pd_n_dims (nd), + pd_base_type (0), + owns_base_type_ (false) +{ + this->pd_dims = this->compute_dims (ds, + nd); +} + +AST_Array::~AST_Array (void) +{ +} + +// Private operations. + +// Compute how many dimensions there are and collect their expressions +// into an array. +AST_Expression ** +AST_Array::compute_dims (UTL_ExprList *ds, + unsigned long nds) +{ + if (ds == 0) + { + return 0; + } + + AST_Expression **result = 0; + ACE_NEW_RETURN (result, + AST_Expression *[nds], + 0); + + UTL_ExprlistActiveIterator iter (ds); + + for (unsigned long i = 0; + !iter.is_done () && i < nds; + iter.next (), i++) + { + AST_Expression *orig = iter.item (); + AST_Expression *copy = 0; + ACE_NEW_RETURN (copy, + AST_Expression (orig, + orig->ev ()->et), + 0); + result[i] = copy; + } + + return result; +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_Array node to the ostream o. +void +AST_Array::dump (ACE_OSTREAM_TYPE &o) +{ + pd_base_type->dump (o); + + this->dump_i (o, " "); + + this->local_name ()->dump (o); + + for (unsigned long i = 0; i < this->pd_n_dims; i++) + { + this->dump_i (o, "["); + + pd_dims[i]->dump (o); + + this->dump_i (o, "]"); + } +} + +int +AST_Array::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_array (this); +} + +// Compute the size type of the node in question. +int +AST_Array::compute_size_type (void) +{ + AST_Type *type = this->base_type (); + + if (!type) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_array::compute_size_type - " + "bad base type\n"), + -1); + } + + // Our size type is the same as our type. + this->size_type (type->size_type ()); + + this->has_constructor (type->has_constructor ()); + + return 0; +} + +// Data accessors. +unsigned long +AST_Array::n_dims (void) +{ + return this->pd_n_dims; +} + +AST_Expression ** +AST_Array::dims (void) +{ + return this->pd_dims; +} + +AST_Type * +AST_Array::base_type (void) const +{ + return this->pd_base_type; +} + +void +AST_Array::set_base_type (AST_Type *nbt) +{ + this->pd_base_type = nbt; + + this->is_local_ = nbt->is_local (); + + if (AST_Decl::NT_sequence == nbt->node_type ()) + { + this->owns_base_type_ = true; + } +} + +bool +AST_Array::legal_for_primary_key (void) const +{ + return this->base_type ()->legal_for_primary_key (); +} + +void +AST_Array::destroy (void) +{ + if (this->owns_base_type_) + { + this->pd_base_type->destroy (); + delete this->pd_base_type; + this->pd_base_type = 0; + } + + for (unsigned long i = 0; i < this->pd_n_dims; ++i) + { + this->pd_dims[i]->destroy (); + delete this->pd_dims[i]; + this->pd_dims[i] = 0; + } + + delete [] this->pd_dims; + this->pd_dims = 0; + this->pd_n_dims = 0; + + this->AST_ConcreteType::destroy (); +} + +void +AST_Array::set_dims (AST_Expression **ds, + unsigned long nds) +{ + this->pd_dims = ds; + this->pd_n_dims = nds; +} + +// Narrowing methods. +IMPL_NARROW_METHODS1(AST_Array, AST_ConcreteType) +IMPL_NARROW_FROM_DECL(AST_Array) diff --git a/TAO/TAO_IDL/ast/ast_attribute.cpp b/TAO/TAO_IDL/ast/ast_attribute.cpp new file mode 100644 index 00000000000..f85b62ed9fc --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_attribute.cpp @@ -0,0 +1,323 @@ +// $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. + +*/ + +// AST_Attribute nodes denote IDL attribute declarations. +// AST_Attribute nodes are AST_Fields with a readonly indication. +// Hence they have a name (an UTL_ScopedName), a type (a subtype +// of AST_Type) and a boolean indicating whether the attribute is +// readonly. + +#include "ast_attribute.h" +#include "ast_exception.h" +#include "ast_visitor.h" +#include "utl_namelist.h" +#include "utl_exceptlist.h" +#include "utl_scope.h" +#include "utl_err.h" +#include "global_extern.h" + +ACE_RCSID (ast, + ast_attribute, + "$Id$") + +// Constructor(s) and destructor. +AST_Attribute::AST_Attribute (void) + : COMMON_Base (), + AST_Decl (), + AST_Field (), + pd_readonly (true), + pd_get_exceptions (0), + pd_set_exceptions (0) +{ +} + +AST_Attribute::AST_Attribute (bool ro, + AST_Type *ft, + UTL_ScopedName *n, + bool local, + bool abstract) + : COMMON_Base (local, + abstract), + AST_Decl (AST_Decl::NT_attr, + n), + AST_Field (AST_Decl::NT_attr, + ft, + n), + pd_readonly (ro), + pd_get_exceptions (0), + pd_set_exceptions (0) +{ +} + +AST_Attribute::~AST_Attribute (void) +{ +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_Attribute to the ostream o. +void +AST_Attribute::dump (ACE_OSTREAM_TYPE &o) +{ + this->dump_i (o, (this->pd_readonly == true ? + "readonly attribute " : "attribute ")); + AST_Field::dump (o); +} + +int +AST_Attribute::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_attribute (this); +} + +void +AST_Attribute::destroy (void) +{ + // No need to delete our exception lists, the + // destroy() method does it. The UTL_ExceptList + // destroy() method does NOT delete the contained + // exception nodes. + + if (this->pd_get_exceptions != 0) + { + this->pd_get_exceptions->destroy (); + this->pd_get_exceptions = 0; + } + + if (this->pd_set_exceptions != 0) + { + this->pd_set_exceptions->destroy (); + this->pd_set_exceptions = 0; + } + + this->AST_Field::destroy (); +} + +UTL_ExceptList * +AST_Attribute::be_add_get_exceptions (UTL_ExceptList *t) +{ + if (this->pd_get_exceptions != 0) + { + idl_global->err ()->error1 (UTL_Error::EIDL_ILLEGAL_RAISES, + this); + } + else + { + this->pd_get_exceptions = t; + } + + return this->pd_get_exceptions; +} + +UTL_ExceptList * +AST_Attribute::be_add_set_exceptions (UTL_ExceptList *t) +{ + if (this->pd_set_exceptions != 0) + { + idl_global->err ()->error1 (UTL_Error::EIDL_ILLEGAL_RAISES, + this); + } + else + { + this->pd_set_exceptions = t; + } + + return this->pd_set_exceptions; +} + +// Data accessors. + +bool +AST_Attribute::readonly (void) const +{ + return this->pd_readonly; +} + +UTL_ExceptList * +AST_Attribute::get_get_exceptions (void) const +{ + return this->pd_get_exceptions; +} + +UTL_ExceptList * +AST_Attribute::get_set_exceptions (void) const +{ + return this->pd_set_exceptions; +} + +// NOTE: No attempt is made to ensure that exceptions are mentioned +// only once.. +UTL_NameList * +AST_Attribute::fe_add_get_exceptions (UTL_NameList *t) +{ + UTL_ScopedName *nl_n = 0; + AST_Exception *fe = 0; + AST_Decl *d = 0; + + this->pd_get_exceptions = 0; + + for (UTL_NamelistActiveIterator nl_i (t); !nl_i.is_done (); nl_i.next ()) + { + nl_n = nl_i.item (); + + d = this->defined_in ()->lookup_by_name (nl_n, + true); + + if (d == 0 || d->node_type() != AST_Decl::NT_except) + { + idl_global->err ()->lookup_error (nl_n); + return 0; + } + + fe = AST_Exception::narrow_from_decl (d); + + if (fe == 0) + { + idl_global->err ()->error1 (UTL_Error::EIDL_ILLEGAL_RAISES, + this); + return 0; + } + + if (this->pd_get_exceptions == 0) + { + ACE_NEW_RETURN (this->pd_get_exceptions, + UTL_ExceptList (fe, + 0), + 0); + } + else + { + UTL_ExceptList *el = 0; + ACE_NEW_RETURN (el, + UTL_ExceptList (fe, + 0), + 0); + + this->pd_get_exceptions->nconc (el); + } + } + + return t; +} + +// NOTE: No attempt is made to ensure that exceptions are mentioned +// only once.. +UTL_NameList * +AST_Attribute::fe_add_set_exceptions (UTL_NameList *t) +{ + UTL_ScopedName *nl_n = 0; + AST_Exception *fe = 0; + AST_Decl *d = 0; + + this->pd_set_exceptions = 0; + + for (UTL_NamelistActiveIterator nl_i (t); !nl_i.is_done (); nl_i.next ()) + { + nl_n = nl_i.item (); + + d = this->defined_in ()->lookup_by_name (nl_n, + true); + + if (d == 0 || d->node_type() != AST_Decl::NT_except) + { + idl_global->err ()->lookup_error (nl_n); + return 0; + } + + fe = AST_Exception::narrow_from_decl (d); + + if (fe == 0) + { + idl_global->err ()->error1 (UTL_Error::EIDL_ILLEGAL_RAISES, + this); + return 0; + } + + if (this->pd_set_exceptions == 0) + { + ACE_NEW_RETURN (this->pd_set_exceptions, + UTL_ExceptList (fe, + 0), + 0); + } + else + { + UTL_ExceptList *el = 0; + ACE_NEW_RETURN (el, + UTL_ExceptList (fe, + 0), + 0); + + this->pd_set_exceptions->nconc (el); + } + } + + return t; +} + +// Narrowing methods. +IMPL_NARROW_METHODS1(AST_Attribute, AST_Field) +IMPL_NARROW_FROM_DECL(AST_Attribute) diff --git a/TAO/TAO_IDL/ast/ast_check.cpp b/TAO/TAO_IDL/ast/ast_check.cpp new file mode 100644 index 00000000000..a4c1afcc73d --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_check.cpp @@ -0,0 +1,146 @@ +// $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. + +*/ + +// The check ensures that for every forward declared struct or union we also +// saw a full definition. + +#include "global_extern.h" +#include "utl_err.h" + +ACE_RCSID (ast, + ast_check, + "$Id$") + +// Static storage for remembering nodes. +static AST_Type **ast_fwds = 0; +static long ast_n_fwds_used = 0; +static long ast_n_fwds_alloc = 0; + +#undef INCREMENT +#define INCREMENT 64 + +// Store a node representing a forward declared struct or union. +void +AST_record_fwd_decl (AST_Type *n) +{ + AST_Type **o_ast_fwds = 0; + long o_ast_n_fwds_alloc = 0; + + // Make sure there's space to store one more. + if (ast_n_fwds_used == ast_n_fwds_alloc) + { + if (ast_n_fwds_alloc == 0) + { + ast_n_fwds_alloc = INCREMENT; + ACE_NEW (ast_fwds, + AST_Type *[ast_n_fwds_alloc]); + } + else + { + o_ast_fwds = ast_fwds; + o_ast_n_fwds_alloc = ast_n_fwds_alloc; + + ast_n_fwds_alloc += INCREMENT; + ACE_NEW (ast_fwds, + AST_Type *[ast_n_fwds_alloc]); + + for (long i = 0; i < o_ast_n_fwds_alloc; i++) + { + ast_fwds[i] = o_ast_fwds[i]; + } + + delete o_ast_fwds; + } + } + + // Insert new node. + ast_fwds[ast_n_fwds_used++] = n; +} + +// Check that all forward declared structs and unions were also defined. +TAO_IDL_FE_Export void +AST_check_fwd_decls (void) +{ + AST_Type *d = 0; + + for (long i = 0; i < ast_n_fwds_used; ++i) + { + d = ast_fwds[i]; + + if (!d->is_defined ()) + { + idl_global->err ()->fwd_decl_not_defined (d); + } + } + + // This method is called once per file in the command line, + // in between which the elements of ast_fwds are destroyed, + // so we have to clean up. + delete [] ast_fwds; + ast_fwds = 0; + ast_n_fwds_alloc = 0; + ast_n_fwds_used = 0; +} diff --git a/TAO/TAO_IDL/ast/ast_component.cpp b/TAO/TAO_IDL/ast/ast_component.cpp new file mode 100644 index 00000000000..6c9e2054984 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_component.cpp @@ -0,0 +1,240 @@ +// $Id$ + +#include "ast_component.h" +#include "ast_attribute.h" +#include "ast_visitor.h" +#include "utl_identifier.h" +#include "utl_indenter.h" +#include "utl_err.h" +#include "global_extern.h" + +ACE_RCSID (ast, + ast_component, + "$Id$") + +AST_Component::AST_Component (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + UTL_Scope (), + AST_Interface (), + pd_base_component (0) +{ +} + +AST_Component::AST_Component (UTL_ScopedName *n, + AST_Component *base_component, + AST_Interface **supports, + long n_supports, + AST_Interface **supports_flat, + long n_supports_flat) + : COMMON_Base (false, + false), + AST_Decl (AST_Decl::NT_component, + n), + AST_Type (AST_Decl::NT_component, + n), + UTL_Scope (AST_Decl::NT_component), + AST_Interface (n, + supports, + n_supports, + supports_flat, + n_supports_flat, + false, + false), + pd_base_component (base_component) +{ +} + +AST_Component::~AST_Component (void) +{ +} + +void +AST_Component::redefine (AST_Interface *from) +{ + AST_Component *c = AST_Component::narrow_from_decl (from); + + if (c == 0) + { + idl_global->err ()->redef_error (from->local_name ()->get_string (), + this->local_name ()->get_string ()); + return; + } + + // Copy over all the base class members. + this->AST_Interface::redefine (from); + + this->pd_base_component = c->pd_base_component; + this->pd_provides = c->pd_provides; + this->pd_uses = c->pd_uses; + this->pd_emits = c->pd_emits; + this->pd_publishes = c->pd_publishes; + this->pd_consumes = c->pd_consumes; +} + +AST_Decl * +AST_Component::look_in_inherited (UTL_ScopedName *e, + bool treat_as_ref) +{ + AST_Decl *d = 0; + + if (this->pd_base_component != 0) + { + d = this->pd_base_component->lookup_by_name (e, treat_as_ref); + } + + return d; +} + +// Look through supported interface list. +AST_Decl * +AST_Component::look_in_supported (UTL_ScopedName *e, + bool treat_as_ref) +{ + AST_Decl *d = 0; + AST_Interface **is = 0; + long nis = -1; + + // Can't look in an interface which was not yet defined. + if (!this->is_defined ()) + { + idl_global->err ()->fwd_decl_lookup (this, + e); + return 0; + } + + // OK, loop through supported interfaces. + + // (Don't leave the inheritance hierarchy, no module or global ...) + // Find all and report ambiguous results as error. + + for (nis = this->n_supports (), is = this->supports (); + nis > 0; + nis--, is++) + { + d = (*is)->lookup_by_name (e, + treat_as_ref, + 0 /* not in parent */); + if (d != 0) + { + break; + } + } + + return d; +} + +AST_Component * +AST_Component::base_component (void) const +{ + return this->pd_base_component; +} + +AST_Interface ** +AST_Component::supports (void) const +{ + return this->inherits (); +} + +long +AST_Component::n_supports (void) const +{ + return this->n_inherits (); +} + +ACE_Unbounded_Queue<AST_Component::port_description> & +AST_Component::provides (void) +{ + return this->pd_provides; +} + +ACE_Unbounded_Queue<AST_Component::port_description> & +AST_Component::uses (void) +{ + return this->pd_uses; +} + +ACE_Unbounded_Queue<AST_Component::port_description> & +AST_Component::emits (void) +{ + return this->pd_emits; +} + +ACE_Unbounded_Queue<AST_Component::port_description> & +AST_Component::publishes (void) +{ + return this->pd_publishes; +} + +ACE_Unbounded_Queue<AST_Component::port_description> & +AST_Component::consumes (void) +{ + return this->pd_consumes; +} + +void +AST_Component::destroy (void) +{ + this->AST_Interface::destroy (); +} + +void +AST_Component::dump (ACE_OSTREAM_TYPE &o) +{ + this->dump_i (o, "component "); + + this->local_name ()->dump (o); + + this->dump_i (o, " "); + + if (this->pd_base_component != 0) + { + this->dump_i (o, ": "); + this->pd_base_component->local_name ()->dump (o); + } + + if (this->pd_n_inherits > 0) + { + this->dump_i (o, "supports "); + + for (long i = 0; i < this->pd_n_inherits; ++i) + { + this->pd_inherits[i]->local_name ()->dump (o); + + if (i < this->pd_n_inherits - 1) + { + this->dump_i (o, ", "); + } + } + } + + this->dump_i (o, " {\n"); + + UTL_Scope::dump (o); + idl_global->indent ()->skip_to (o); + + this->dump_i (o, "}"); +} + +int +AST_Component::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_component (this); +} + +bool +AST_Component::redef_clash (void) +{ + if (this->AST_Interface::redef_clash ()) + { + return 1; + } + + return 0; +} + +// Narrowing methods. +IMPL_NARROW_METHODS1(AST_Component, AST_Interface) +IMPL_NARROW_FROM_DECL(AST_Component) +IMPL_NARROW_FROM_SCOPE(AST_Component) diff --git a/TAO/TAO_IDL/ast/ast_component_fwd.cpp b/TAO/TAO_IDL/ast/ast_component_fwd.cpp new file mode 100644 index 00000000000..3f4a10f8a93 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_component_fwd.cpp @@ -0,0 +1,61 @@ +// $Id$ + +#include "ast_component_fwd.h" +#include "ast_visitor.h" +#include "utl_identifier.h" + +ACE_RCSID( ast, + ast_component_fwd, + "$Id$") + +AST_ComponentFwd::AST_ComponentFwd (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + AST_InterfaceFwd () +{ +} + +AST_ComponentFwd::AST_ComponentFwd (AST_Interface *dummy, + UTL_ScopedName *n) + : COMMON_Base (true, + false), + AST_Decl (AST_Decl::NT_component_fwd, + n), + AST_Type (AST_Decl::NT_component_fwd, + n), + AST_InterfaceFwd (dummy, + n) +{ +} + +AST_ComponentFwd::~AST_ComponentFwd (void) +{ +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_InterfaceFwd node to the ostream o. +void +AST_ComponentFwd::dump (ACE_OSTREAM_TYPE &o) +{ + this->dump_i (o, "component "); + + this->local_name ()->dump (o); +} + +int +AST_ComponentFwd::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_component_fwd (this); +} + +void +AST_ComponentFwd::destroy (void) +{ + this->AST_InterfaceFwd::destroy (); +} + +// Narrowing methods. +IMPL_NARROW_METHODS1 (AST_ComponentFwd, AST_InterfaceFwd) +IMPL_NARROW_FROM_DECL (AST_ComponentFwd) diff --git a/TAO/TAO_IDL/ast/ast_concrete_type.cpp b/TAO/TAO_IDL/ast/ast_concrete_type.cpp new file mode 100644 index 00000000000..ce30ecfff39 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_concrete_type.cpp @@ -0,0 +1,106 @@ +// $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. + +*/ + +// AST_ConcreteType nodes denote all non-interface types of IDL. +// They are AST_Type nodes. + +#include "ast_concrete_type.h" + +ACE_RCSID (ast, + ast_concrete_type, + "$Id$") + +// Constructor(s) and destructor. +AST_ConcreteType::AST_ConcreteType (void) + : COMMON_Base (), + AST_Decl (), + AST_Type () +{ +} + +AST_ConcreteType::AST_ConcreteType (AST_Decl::NodeType nt, + UTL_ScopedName *n) + : COMMON_Base (), + AST_Decl (nt, + n), + AST_Type (nt, + n) +{ +} + +AST_ConcreteType::~AST_ConcreteType (void) +{ +} + +void +AST_ConcreteType::destroy (void) +{ + this->AST_Type::destroy (); +} + +// Narrowing methods. +IMPL_NARROW_METHODS1(AST_ConcreteType, AST_Type) +IMPL_NARROW_FROM_DECL(AST_ConcreteType) diff --git a/TAO/TAO_IDL/ast/ast_constant.cpp b/TAO/TAO_IDL/ast/ast_constant.cpp new file mode 100644 index 00000000000..2ff7bad52cd --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_constant.cpp @@ -0,0 +1,318 @@ +// $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. + +*/ + +// AST_Constant nodes denote IDL constant declarations. +// AST_Constants have a value (an AST_Expression) and a value type +// (a value from the enum AST_Expression::ExprType). +// AST_Constant has two constructors, one for use in creating constants +// and the other for use in creating enumerators (see the class +// AST_EnumVal). + +#include "ast_constant.h" +#include "utl_identifier.h" +#include "ast_visitor.h" +#include "ast_generator.h" +#include "nr_extern.h" + +ACE_RCSID (ast, + ast_constant, + "$Id$") + +// Static functions. + +// Convert a value from the enum AST_Expression::ExprType to a char *. +const char * +AST_Constant::exprtype_to_string (AST_Expression::ExprType et) +{ + switch (et) + { + case AST_Expression::EV_short: + return "Short"; + case AST_Expression::EV_ushort: + return "UShort"; + case AST_Expression::EV_long: + return "Long"; + case AST_Expression::EV_ulong: + return "ULong"; + case AST_Expression::EV_float: + return "Float"; + case AST_Expression::EV_double: + return "Double"; + case AST_Expression::EV_char: + return "Char"; + case AST_Expression::EV_octet: + return "Octet"; + case AST_Expression::EV_bool: + return "Boolean"; + case AST_Expression::EV_string: + return "Char*"; + case AST_Expression::EV_ulonglong: + return "ULongLong"; + case AST_Expression::EV_longlong: + return "LongLong"; + case AST_Expression::EV_wchar: + return "Wchar"; + case AST_Expression::EV_wstring: + return "Wchar*"; + case AST_Expression::EV_longdouble: + return "LongDouble"; + default: + break; + } + + return 0; +} + +// Constructor(s) and destructor. + +// Default constructor. +AST_Constant::AST_Constant (void) + : COMMON_Base (), + AST_Decl (), + pd_constant_value (0), + pd_et (AST_Expression::EV_none), + ifr_added_ (0) +{ +} + +// Used in constructing AST_EnumVal nodes. +AST_Constant::AST_Constant (AST_Expression::ExprType t, + AST_Decl::NodeType nt, + AST_Expression *v, + UTL_ScopedName *n) + : COMMON_Base (), + AST_Decl (nt, + n), + pd_constant_value (v), + pd_et (t), + ifr_added_ (0) +{ +} + +// Used when constructing AST_Constant nodes. +AST_Constant::AST_Constant (AST_Expression::ExprType t, + AST_Expression *v, + UTL_ScopedName *n) + : COMMON_Base (), + AST_Decl (AST_Decl::NT_const, + n), + pd_constant_value (v), + pd_et (t), + ifr_added_ (0) +{ + // Avoids a truncation warning on MSVC when assigning a decimal + // literal to a float constant. Must also check that the input + // expression is of type double (indicates that we are being + // assigned from a literal). If v is of type float, it may be + // a constant-to-constant assignment - in any case the danger + // of truncation would not apply. + if (t == AST_Expression::EV_float && v->ev ()->et == AST_Expression::EV_double) + { + AST_Expression::AST_ExprValue *ev = + this->pd_constant_value->ev (); + ev->et = t; + ev->u.fval = (float) ev->u.dval; + } + // Allows the enum value string name to be used in generating the + // rhs of the constant assignment. + else if (t == AST_Expression::EV_enum) + { + this->pd_constant_value->ev ()->et = t; + } +} + +AST_Constant::~AST_Constant (void) +{ +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_Constant node to the ostream o. +void +AST_Constant::dump (ACE_OSTREAM_TYPE &o) +{ + this->dump_i (o, "const "); + this->dump_i (o, this->exprtype_to_string ()); + this->dump_i (o, " "); + + this->local_name ()->dump (o); + + this->dump_i (o, " = "); + + this->pd_constant_value->dump (o); +} + +int +AST_Constant::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_constant (this); +} + +void +AST_Constant::destroy (void) +{ + if (this->pd_constant_value != 0) + { + this->pd_constant_value->destroy (); + delete this->pd_constant_value; + this->pd_constant_value = 0; + } + + this->AST_Decl::destroy (); +} + +// Data accessors. + +AST_Expression * +AST_Constant::constant_value (void) +{ + return this->pd_constant_value; +} + +AST_Expression::ExprType +AST_Constant::et (void) +{ + return this->pd_et; +} + +bool +AST_Constant::ifr_added (void) +{ + return this->ifr_added_; +} + +void +AST_Constant::ifr_added (bool val) +{ + this->ifr_added_ = val; +} + +const char * +AST_Constant::exprtype_to_string (void) +{ + switch (this->pd_et) + { + case AST_Expression::EV_short: + return "CORBA::Short"; + case AST_Expression::EV_ushort: + return "CORBA::UShort"; + case AST_Expression::EV_long: + return "CORBA::Long"; + case AST_Expression::EV_ulong: + return "CORBA::ULong"; + case AST_Expression::EV_float: + return "CORBA::Float"; + case AST_Expression::EV_double: + return "CORBA::Double"; + case AST_Expression::EV_char: + return "CORBA::Char"; + case AST_Expression::EV_octet: + return "CORBA::Octet"; + case AST_Expression::EV_bool: + return "CORBA::Boolean"; + case AST_Expression::EV_string: + return "char *const"; + case AST_Expression::EV_void: + return "void"; + case AST_Expression::EV_none: + return "none"; + case AST_Expression::EV_longlong: + return "CORBA::LongLong"; + case AST_Expression::EV_ulonglong: + return "CORBA::ULongLong"; + case AST_Expression::EV_wchar: + return "CORBA::WChar"; + case AST_Expression::EV_wstring: + return "CORBA::WChar *const"; + case AST_Expression::EV_enum: + case AST_Expression::EV_longdouble: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + return 0; + } + + return 0; +} + +UTL_ScopedName * +AST_Constant::enum_full_name (void) +{ + if (this->pd_et == AST_Expression::EV_enum) + { + UTL_Scope *s = this->defined_in (); + AST_Decl *d = s->lookup_by_name (this->pd_constant_value->n (), + 1); + return (ScopeAsDecl (d->defined_in ()))->name (); + } + else + { + return 0; + } +} + +// Narrowing methods. +IMPL_NARROW_METHODS1(AST_Constant, AST_Decl) +IMPL_NARROW_FROM_DECL(AST_Constant) diff --git a/TAO/TAO_IDL/ast/ast_decl.cpp b/TAO/TAO_IDL/ast/ast_decl.cpp new file mode 100644 index 00000000000..4db72002251 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_decl.cpp @@ -0,0 +1,1459 @@ +// $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. + +*/ + +/* + * AST_Decl is the base class for all AST nodes except AST_Expression. + * AST_Decls have a node type (a value from the enum AST_Decl::NodeType) + * and a name (a UTL_ScopedName). + * Additionally AST_Decl nodes record the scope of definition, the + * file name in which they were defined, the line on which they were + * defined in that file, and a boolean denoting whether this is the + * main file or an #include'd file. + */ + +#include "ast_interface.h" +#include "ast_module.h" +#include "ast_array.h" +#include "ast_field.h" +#include "ast_structure.h" +#include "ast_sequence.h" +#include "ast_string.h" +#include "ast_typedef.h" +#include "ast_visitor.h" +#include "global_extern.h" +#include "nr_extern.h" +#include "utl_identifier.h" +#include "utl_string.h" +#include "utl_scope.h" +#include "utl_err.h" +#include "ace/OS_NS_stdio.h" + +// FUZZ: disable check_for_streams_include +#include "ace/streams.h" + +ACE_RCSID (ast, + ast_decl, + "$Id$") + +COMMON_Base::COMMON_Base (bool local, + bool abstract) + : is_local_ (local), + is_abstract_ (abstract) +{ +} + +bool +COMMON_Base::is_local (void) +{ + return this->is_local_; +} + +void +COMMON_Base::is_local (bool val) +{ + this->is_local_ = val; +} + +bool +COMMON_Base::is_abstract (void) const +{ + return this->is_abstract_; +} + +void +COMMON_Base::is_abstract (bool val) +{ + this->is_abstract_ = val; +} + +void +COMMON_Base::destroy (void) +{ +} + +// Constructor(s) and destructor. + +AST_Decl::AST_Decl (void) + : COMMON_Base (), + repoID_ (0), + flat_name_ (0), + contains_wstring_ (-1), + pd_imported (false), + pd_in_main_file (false), + pd_defined_in (0), + pd_node_type (NT_module), + pd_line (-1), + pd_local_name (0), + pd_original_local_name (0), + pd_added (false), + full_name_ (0), + prefix_ (0), + version_ (0), + anonymous_ (false), + typeid_set_ (false), + last_referenced_as_ (0), + prefix_scope_ (0) +{ +} + +AST_Decl::AST_Decl (NodeType nt, + UTL_ScopedName *n, + bool anonymous) + : COMMON_Base (), + repoID_ (0), + flat_name_ (0), + contains_wstring_ (-1), + pd_imported (idl_global->imported ()), + pd_in_main_file (idl_global->in_main_file ()), + pd_defined_in (idl_global->scopes ().depth () > 0 + ? idl_global->scopes ().top () + : 0), + pd_node_type (nt), + pd_line (idl_global->lineno ()), + pd_name (0), + pd_local_name (n == 0 ? 0 : n->last_component ()->copy ()), + pd_original_local_name (0), + pd_added (false), + full_name_ (0), + prefix_ (0), + version_ (0), + anonymous_ (anonymous), + typeid_set_ (false), + last_referenced_as_ (0), + prefix_scope_ (0) +{ + // If this is the root node, the filename won't have been set yet. + UTL_String *fn = idl_global->filename (); + this->pd_file_name = (fn != 0 ? fn->get_string () : ""); + + this->compute_full_name (n); + + char *prefix = 0; + idl_global->pragma_prefixes ().top (prefix); + + if (prefix == 0) + { + this->prefix_ = ACE::strnew (""); + } + else + { + this->prefix_ = ACE::strnew (prefix); + } + + if (n != 0) + { + // The function body creates its own copy. + this->original_local_name (n->last_component ()); + } + + this->compute_repoID (); +} + +AST_Decl::~AST_Decl (void) +{ +} + +// Private operations. + +// Compute our private UTL_ScopedName member. +void +AST_Decl::compute_full_name (UTL_ScopedName *n) +{ + // This should happen only when we are a non-void predefined type, + // in which case our scoped name has already been created by the + // AST_PredefinedType constructor. + if (n == 0) + { + return; + } + + UTL_ScopedName *cn = 0; + AST_Decl *d = 0; + + // Initialize this name to 0. + this->pd_name = 0; + + // Global scope? + if (this->defined_in () == 0) + { + this->pd_name = (UTL_IdList *) n->copy (); + return; + } + + // OK, not global. So copy name of containing scope, then + // smash last cdr of copy with new component + d = ScopeAsDecl (this->defined_in ()); + + if (d != 0) + { + cn = d->name (); + } + + if (cn != 0) + { + this->pd_name = (UTL_IdList *) cn->copy (); + } + + if (this->pd_local_name != 0) + { + if (this->pd_name == 0) + { + ACE_NEW (this->pd_name, + UTL_ScopedName (this->pd_local_name->copy (), + 0)); + } + else + { + UTL_ScopedName *conc_name = 0; + ACE_NEW (conc_name, + UTL_ScopedName (this->pd_local_name->copy (), + 0)); + + this->pd_name->nconc (conc_name); + } + } +} + +void +AST_Decl::set_prefix_with_typeprefix_r (const char *value, + UTL_Scope *appeared_in) +{ + if (this->typeid_set_) + { + return; + } + + if (this->prefix_scope_ != 0) + { + AST_Decl *decl = ScopeAsDecl (this->prefix_scope_); + + bool const overridden = + decl->has_ancestor (ScopeAsDecl (appeared_in)); + + if (overridden) + { + return; + } + } + + delete [] this->repoID_; + this->repoID_ = 0; + this->prefix (value); + this->prefix_scope_ = appeared_in; + + UTL_Scope *s = DeclAsScope (this); + + if (s != 0) + { + AST_Decl *tmp = 0; + UTL_Scope *s_tmp = 0; + + for (UTL_ScopeActiveIterator i (s, UTL_Scope::IK_decls); + !i.is_done (); + i.next ()) + { + tmp = i.item (); + s_tmp = DeclAsScope (tmp); + + if (s_tmp == 0) + { + continue; + } + + tmp->set_prefix_with_typeprefix_r (value, + appeared_in); + } + } + + // This will recursively catch all previous openings of a module. + if (this->node_type () == AST_Decl::NT_module) + { + AST_Decl **d = 0; + AST_Module *m = AST_Module::narrow_from_decl (this); + + for (ACE_Unbounded_Set_Iterator<AST_Decl *> iter (m->previous ()); + !iter.done (); + iter.advance ()) + { + iter.next (d); + + if ((*d)->node_type () == AST_Decl::NT_pre_defined) + { + continue; + } + + (*d)->set_prefix_with_typeprefix_r (value, + appeared_in); + } + } + + this->compute_repoID (); +} + +// Protected operations. + +// Compute stringified fully scoped name. +void +AST_Decl::compute_full_name (void) +{ + if (this->full_name_ != 0) + { + return; + } + else + { + size_t namelen = 0; + long first = true; + long second = false; + char *name = 0; + + for (UTL_IdListActiveIterator i (this->name ()); + !i.is_done (); + i.next ()) + { + if (!first) + { + namelen += 2; // for "::" + } + else if (second) + { + first = second = false; + } + + // Print the identifier. + name = i.item ()->get_string (); + namelen += ACE_OS::strlen (name); + + if (first) + { + if (ACE_OS::strcmp (name, "") != 0) + { + // Does not start with a "". + first = false; + } + else + { + second = true; + } + } + } + + ACE_NEW (this->full_name_, + char[namelen + 1]); + + this->full_name_[0] = '\0'; + first = true; + second = false; + + for (UTL_IdListActiveIterator j (this->name ()); + !j.is_done (); + j.next ()) + { + if (!first) + { + ACE_OS::strcat (this->full_name_, "::"); + } + else if (second) + { + first = second = false; + } + + // Print the identifier. + name = j.item ()->get_string (); + ACE_OS::strcat (this->full_name_, name); + + if (first) + { + if (ACE_OS::strcmp (name, "") != 0) + { + // Does not start with a "". + first = false; + } + else + { + second = true; + } + } + } + } +} + +// Compute stringified repository ID. +void +AST_Decl::compute_repoID (void) +{ + if (this->repoID_ != 0) + { + return; + } + + size_t namelen = 4; // for the prefix "IDL:" + long first = true; + long second = false; + char *name = 0; + const char *prefix = (this->prefix_ ? this->prefix_ : ""); + UTL_Scope *scope = this->defined_in (); + const char *parent_prefix = 0; + + // If our prefix is empty, we check to see if an ancestor has one. + while (ACE_OS::strcmp (prefix, "") == 0 && scope != 0) + { + AST_Decl *parent = ScopeAsDecl (scope); + + if (parent->node_type () == AST_Decl::NT_root + && parent->imported ()) + { + break; + } + + parent_prefix = parent->prefix (); + prefix = (parent_prefix ? parent_prefix : ""); + scope = parent->defined_in (); + } + + // in the first loop compute the total length + namelen += ACE_OS::strlen (prefix) + 1; + + const char *version = this->version_; + scope = this->defined_in (); + + // If our version is has not bee set, we use the parent's, if any. + while (version == 0 && scope != 0) + { + AST_Decl *parent = ScopeAsDecl (scope); + version = parent->version_; + scope = parent->defined_in (); + } + + if (version != 0) + { + // Version member string + ':' + namelen += ACE_OS::strlen (version) + 1; + } + else + { + // For ":1.0" + namelen += 4; + } + + for (UTL_IdListActiveIterator i (this->name ()); + !i.is_done (); + i.next ()) + { + if (!first) + { + namelen += 1; // for "/" + } + else if (second) + { + first = second = false; + } + + // Print the identifier. + name = i.item ()->get_string (); + size_t item_len = ACE_OS::strlen (name); + + if (ACE_OS::strstr (name, "_cxx_") == name) + { + namelen += (item_len - ACE_OS::strlen ("_cxx_")); + } + else + { + namelen += item_len; + } + + if (first) + { + if (ACE_OS::strcmp (name, "") != 0) + { + // Does not start with a "". + first = false; + } + else + { + second = true; + } + } + } + + ACE_NEW (this->repoID_, + char[namelen + 1]); + + this->repoID_[0] = '\0'; + + ACE_OS::sprintf (this->repoID_, + "%s", + "IDL:"); + + if (ACE_OS::strcmp (prefix, "") != 0) + { + ACE_OS::strcat (this->repoID_, + prefix); + + ACE_OS::strcat (this->repoID_, "/"); + } + + first = true; + second = false; + + for (UTL_IdListActiveIterator j (this->name ()); + !j.is_done (); + j.next ()) + { + if (!first) + { + ACE_OS::strcat (this->repoID_, "/"); + } + else if (second) + { + first = second = false; + } + + // Print the identifier. + name = j.item ()->get_string (); + + if (ACE_OS::strstr (name, "_cxx_") == name) + { + ACE_OS::strcat (this->repoID_, + name + ACE_OS::strlen ("_cxx_")); + } + else + { + ACE_OS::strcat (this->repoID_, + name); + } + + if (first) + { + if (ACE_OS::strcmp (name, "") != 0) + { + // Does not start with a "". + first = false; + } + else + { + second = true; + } + } + } + + if (version != 0) + { + ACE_OS::strcat (this->repoID_, + ":"); + ACE_OS::strcat (this->repoID_, + version); + } + else + { + ACE_OS::strcat (this->repoID_, + ":1.0"); + } +} + +// Public operations. + +const char * +AST_Decl::flat_name (void) +{ + if (!this->flat_name_) + { + this->compute_flat_name (); + } + + return this->flat_name_; +} + +// Compute stringified flattened fully scoped name. +void +AST_Decl::compute_flat_name (void) +{ + if (this->flat_name_ != 0) + { + return; + } + else + { + size_t namelen = 0; + long first = true; + long second = false; + char *item_name = 0; + + // In the first loop, compute the total length. + for (UTL_IdListActiveIterator i (this->name ()); + !i.is_done (); + i.next ()) + { + if (!first) + { + namelen += 1; // for "_" + } + else if (second) + { + first = second = false; + } + + // Print the identifier. + item_name = i.item ()->get_string (); + namelen += ACE_OS::strlen (item_name); + + if (first) + { + if (ACE_OS::strcmp (item_name, "") != 0) + { + // Does not start with a "". + first = false; + } + else + { + second = true; + } + } + } + + ACE_NEW (this->flat_name_, + char[namelen + 1]); + + this->flat_name_[0] = '\0'; + first = true; + second = false; + + for (UTL_IdListActiveIterator j (this->name ()); + !j.is_done (); + j.next ()) + { + if (!first) + { + ACE_OS::strcat (this->flat_name_, "_"); + } + else if (second) + { + first = second = false; + } + + // Print the identifier. + item_name = j.item ()->get_string (); + ACE_OS::strcat (this->flat_name_, item_name); + + if (first) + { + if (ACE_OS::strcmp (item_name, "") != 0) + { + // Does not start with a "". + first = false; + } + else + { + second = true; + } + } + } + } +} + +// Return TRUE if one of my ancestor scopes is "s" +// and FALSE otherwise. +bool +AST_Decl::has_ancestor (AST_Decl *s) +{ + if (this == s) + { + return true; + } + + if (s->node_type () == AST_Decl::NT_module) + { + UTL_Scope *enclosing = s->defined_in (); + AST_Decl *other_opening = s; + + for (int index = 1; other_opening != 0; ++index) + { + if (this == other_opening) + { + return true; + } + + other_opening = enclosing->lookup_by_name_local (s->local_name (), + index); + } + } + + if (this->pd_defined_in == 0) + { + return false; + } + + return ScopeAsDecl (this->pd_defined_in)->has_ancestor (s); +} + +bool +AST_Decl::is_child (AST_Decl *s) +{ + if (this->defined_in ()) + { + AST_Decl *d = ScopeAsDecl (this->defined_in ()); + + if (d == 0) + { + return 0; + } + + if (ACE_OS::strcmp (d->full_name (), s->full_name ()) == 0) + { + return 1; + } + } + + return 0; // Not a child. +} + +bool +AST_Decl::is_nested (void) +{ + AST_Decl *d = ScopeAsDecl (this->defined_in ()); + + // If we have an outermost scope and if that scope is not that of the Root, + // then we are defined at some nesting level. + if (d != 0 && d->node_type () != AST_Decl::NT_root) + { + return true; + } + + return false; +} + +// Dump this AST_Decl to the ostream o. +void +AST_Decl::dump (ACE_OSTREAM_TYPE &o) +{ + this->pd_local_name->dump (o); +} + +void +AST_Decl::dump_i (ACE_OSTREAM_TYPE &o, const char *s) const +{ + // Have to use ACE_CString here to avoid ambiguous overload error, see + // SString.h for an the overloaded operator << () methods. + o << ACE_CString(s); +} + +int +AST_Decl::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_decl (this); +} + +void +AST_Decl::destroy (void) +{ + // These are not set for the root node. + if (this->pd_name != 0) + { + this->pd_name->destroy (); + delete this->pd_name; + this->pd_name = 0; + } + + if (this->pd_local_name != 0) + { + this->pd_local_name->destroy (); + delete this->pd_local_name; + this->pd_local_name = 0; + } + + if (this->pd_original_local_name != 0) + { + this->pd_original_local_name->destroy (); + delete this->pd_original_local_name; + this->pd_original_local_name = 0; + } + + if (this->last_referenced_as_ != 0) + { + this->last_referenced_as_->destroy (); + delete this->last_referenced_as_; + this->last_referenced_as_ = 0; + } + + delete [] this->full_name_; + this->full_name_ = 0; + + delete [] this->repoID_; + this->repoID_ = 0; + + delete [] this->prefix_; + this->prefix_ = 0; + + delete [] this->version_; + this->version_ = 0; + + delete [] this->flat_name_; + this->flat_name_ = 0; +} + +// Data accessors. + +const char * +AST_Decl::full_name (void) +{ + if (this->full_name_ == 0) + { + compute_full_name (); + } + + return this->full_name_; +} + +const char * +AST_Decl::repoID (void) +{ + if (this->pd_node_type == NT_root) + { + delete [] this->repoID_; + this->repoID_ = ACE::strnew (""); + } + + if (this->repoID_ == 0) + { + this->compute_repoID (); + } + + return this->repoID_; +} + +void +AST_Decl::repoID (char *value) +{ + if (this->repoID_ != 0) + { + delete [] this->repoID_; + } + + this->repoID_ = value; +} + +const char * +AST_Decl::prefix (void) +{ + return this->prefix_; +} + +void +AST_Decl::prefix (const char *value) +{ + delete [] this->prefix_; + this->prefix_ = ACE::strnew (value); +} + +const char * +AST_Decl::version (void) +{ + if (this->version_ == 0) + { + // Calling the method will compute if necessary. + const char *repo_id = this->repoID (); + + // All forms of repo id should contain two colons, the + // version coming after the second one. + const char *tail1 = 0; + const char *tail2 = 0; + + if (repo_id != 0) + { + tail1 = ACE_OS::strchr (repo_id, + ':'); + } + + if (tail1 != 0) + { + tail2 = ACE_OS::strchr (tail1 + 1, + ':'); + } + + if (! this->typeid_set_ && tail2 != 0) + { + this->version_ = ACE::strnew (tail2 + 1); + } + else + { + this->version_ = ACE::strnew ("1.0"); + } + } + + return this->version_; +} + +void +AST_Decl::version (char *value) +{ + // Previous #pragma version or #pragma id make this illegal. + if ((this->version_ == 0 || ACE_OS::strcmp (this->version_, value) == 0) + && ! this->typeid_set_) + { + delete [] this->version_; + this->version_ = value; + + // Repo id is now computed eagerly, so a version set must update + // is as well. + if (this->repoID_ != 0) + { + ACE_CString tmp (this->repoID_); + ACE_CString::size_type const pos = tmp.rfind (':'); + + if (pos != ACE_CString::npos) + { + tmp = tmp.substr (0, pos + 1) + value; + delete [] this->repoID_; + this->repoID_ = ACE::strnew (tmp.fast_rep ()); + } + } + } + else + { + idl_global->err ()->version_reset_error (); + } +} + +bool +AST_Decl::anonymous (void) const +{ + return this->anonymous_; +} + +void +AST_Decl::anonymous (bool val) +{ + this->anonymous_ = val; +} + +bool +AST_Decl::typeid_set (void) const +{ + return this->typeid_set_; +} + +void +AST_Decl::typeid_set (bool val) +{ + this->typeid_set_ = val; +} + +void +AST_Decl::set_id_with_typeid (char *value) +{ + // Can't call 'typeid' twice, even with the same value. + if (this->typeid_set ()) + { + idl_global->err ()->error1 (UTL_Error::EIDL_TYPEID_RESET, + this); + } + + // Are we a legal type for 'typeid'? + switch (this->pd_node_type) + { + case AST_Decl::NT_field: + { + AST_Interface *iface = + AST_Interface::narrow_from_scope (this->defined_in ()); + + if (iface == 0 || iface->node_type () == AST_Decl::NT_valuetype == 0) + { + idl_global->err ()->error1 (UTL_Error::EIDL_INVALID_TYPEID, + this); + + return; + } + + break; + } + case AST_Decl::NT_module: + case AST_Decl::NT_interface: + case AST_Decl::NT_const: + case AST_Decl::NT_typedef: + case AST_Decl::NT_except: + case AST_Decl::NT_attr: + case AST_Decl::NT_op: + case AST_Decl::NT_enum: + case AST_Decl::NT_factory: + case AST_Decl::NT_component: + case AST_Decl::NT_home: + case AST_Decl::NT_eventtype: + break; + default: + idl_global->err ()->error1 (UTL_Error::EIDL_INVALID_TYPEID, + this); + + return; + } + + delete [] this->repoID_; + this->repoID_ = 0; + this->repoID (ACE::strnew (value)); + this->typeid_set_ = true; +} + +void +AST_Decl::set_prefix_with_typeprefix (const char *value) +{ + // Are we a legal type for 'typeprefix'? This is checked only at + // the top level. + switch (this->pd_node_type) + { + case AST_Decl::NT_module: + case AST_Decl::NT_interface: + case AST_Decl::NT_valuetype: + case AST_Decl::NT_eventtype: + case AST_Decl::NT_struct: + case AST_Decl::NT_union: + case AST_Decl::NT_except: + break; + default: + idl_global->err ()->error1 (UTL_Error::EIDL_INVALID_TYPEPREFIX, + this); + + return; + } + + this->set_prefix_with_typeprefix_r (value, + DeclAsScope (this)); +} + +bool +AST_Decl::imported (void) +{ + return this->pd_imported; +} + +void +AST_Decl::set_imported (bool is_it) +{ + this->pd_imported = is_it; +} + +bool +AST_Decl::in_main_file (void) +{ + return this->pd_in_main_file; +} + +void +AST_Decl::set_in_main_file (bool is_it) +{ + this->pd_in_main_file = is_it; +} + +bool +AST_Decl::added (void) +{ + return this->pd_added; +} + +void +AST_Decl::set_added (bool is_it) +{ + this->pd_added = is_it; +} + +UTL_Scope * +AST_Decl::defined_in (void) +{ + return this->pd_defined_in; +} + +void +AST_Decl::set_defined_in (UTL_Scope *s) +{ + this->pd_defined_in = s; +} + +AST_Decl::NodeType +AST_Decl::node_type (void) +{ + return this->pd_node_type; +} + +long +AST_Decl::line (void) +{ + return this->pd_line; +} + +void +AST_Decl::set_line (long l) +{ + this->pd_line = l; +} + +ACE_CString +AST_Decl::file_name (void) +{ + return this->pd_file_name; +} + +void +AST_Decl::set_file_name (ACE_CString s) +{ + this->pd_file_name = s; +} + +UTL_ScopedName * +AST_Decl::name (void) +{ + return this->pd_name; +} + +// @@ Wherever compute_* are called, we should remember to delete them +// after use. + +// Variation of the <name>. Computes scoped name string, applying +// prefix and suffix to the local name component. +UTL_ScopedName * +AST_Decl::compute_name (const char *prefix, + const char *suffix) +{ + if (prefix == 0 || suffix == 0) + { + return 0; + } + + UTL_ScopedName *result_name = 0; + + // Prepare prefix_<local_name>_suffix string. + + ACE_CString suffix_str (suffix); + ACE_CString local_str (this->local_name ()->get_string ()); + + ACE_CString result_local_str (prefix); + result_local_str += local_str; + result_local_str += suffix_str; + + // Identifier for the resulting local name. + Identifier *result_local_id = 0; + ACE_NEW_RETURN (result_local_id, + Identifier (result_local_str.c_str ()), + 0); + + // UTL_Scoped name for the resulting local name. + UTL_ScopedName *result_local_name = 0; + ACE_NEW_RETURN (result_local_name, + UTL_ScopedName (result_local_id, + 0), + 0); + + // Global scope? + if (this->defined_in () == 0) + { + result_name = result_local_name; + } + else + { + // OK, not global. So copy name of containing scope, then + // smash last cdr of copy with new component. + + AST_Decl *d = ScopeAsDecl (this->defined_in ()); + + if (d != 0) + { + UTL_ScopedName *cn = d->name (); + + if (cn != 0) + { + result_name = (UTL_ScopedName *) cn->copy (); + + if (result_name == 0) + { + result_name = result_local_name; + } + else + { + result_name->nconc (result_local_name); + } + } + } + } + + return result_name; +} + +void +AST_Decl::set_name (UTL_ScopedName *n) +{ + if (this->pd_name == n) + { + return; + } + + if (this->pd_name != 0) + { + this->pd_name->destroy (); + delete this->pd_name; + } + + this->pd_name = n; + + if (n != 0) + { + if (this->pd_local_name != 0) + { + this->pd_local_name->destroy (); + delete this->pd_local_name; + } + + this->pd_local_name = n->last_component ()->copy (); + + // The name without _cxx_ prefix removed, if there was any. + if (this->pd_original_local_name != 0) + { + this->pd_original_local_name->destroy (); + delete this->pd_original_local_name; + } + + this->original_local_name (n->last_component ()); + } +} + +Identifier * +AST_Decl::local_name (void) +{ + return this->pd_local_name; +} + +void +AST_Decl::local_name (Identifier *id) +{ + if (this->pd_local_name != 0) + { + this->pd_local_name->destroy (); + } + + delete this->pd_local_name; + this->pd_local_name = id; +} + +Identifier * +AST_Decl::compute_local_name (const char *prefix, + const char *suffix) +{ + if (prefix == 0 || suffix == 0) + { + return 0; + } + + // Init the result with prefix. + ACE_CString result_str (prefix); + + // Put local. + result_str += ACE_CString (this->local_name ()->get_string ()); + + // Put suffix. + result_str += ACE_CString (suffix); + + // Identifier for the resulting local name. + Identifier *result_id = 0; + ACE_NEW_RETURN (result_id, + Identifier (result_str.c_str ()), + 0); + + return result_id; +} + +// If there is _cxx_ in the beginning, we will remove that and keep +// a copy of the original name. TAO IDL's front end adds _cxx_ +// prefix to the all the reserved keywords. But when we invoke the +// operation remotely, we should be sending only the name with out +// "_cxx_" prefix. +void +AST_Decl::original_local_name (Identifier *local_name) +{ + // Remove _cxx_ if it is present. + if (ACE_OS::strstr (local_name->get_string (), + "_cxx_") + == local_name->get_string ()) + { + // CSting class is good to do this stuff. + ACE_CString name_str (local_name->get_string ()); + + // Remove _cxx_. + name_str = name_str.substr (ACE_OS::strlen ("_cxx_")); + + // Assign to the Identifier variable. + ACE_NEW (this->pd_original_local_name, + Identifier (name_str.c_str ())); + } + else + { + this->pd_original_local_name = local_name->copy (); + } +} + +Identifier * +AST_Decl::original_local_name (void) +{ + return this->pd_original_local_name; +} + +UTL_ScopedName * +AST_Decl::last_referenced_as (void) const +{ + return this->last_referenced_as_; +} + +void +AST_Decl::last_referenced_as (UTL_ScopedName *n) +{ + if (this->last_referenced_as_ != 0) + { + this->last_referenced_as_->destroy (); + } + + delete this->last_referenced_as_; + this->last_referenced_as_ = n; +} + +UTL_Scope * +AST_Decl::prefix_scope (void) +{ + return this->prefix_scope_; +} + +void +AST_Decl::prefix_scope (UTL_Scope *s) +{ + this->prefix_scope_ = s; +} + +// Container types will override this. +int +AST_Decl::contains_wstring (void) +{ + if (this->contains_wstring_ == -1) + { + switch (this->node_type ()) + { + case AST_Decl::NT_array: + { + AST_Array *a = AST_Array::narrow_from_decl (this); + this->contains_wstring_ = + a->base_type ()->contains_wstring (); + break; + } + case AST_Decl::NT_except: + case AST_Decl::NT_struct: + case AST_Decl::NT_union: + { + AST_Structure *s = AST_Structure::narrow_from_decl (this); + this->contains_wstring_ = + s->contains_wstring (); + break; + } + case AST_Decl::NT_sequence: + { + AST_Sequence *s = AST_Sequence::narrow_from_decl (this); + this->contains_wstring_ = + s->base_type ()->contains_wstring (); + break; + } + case AST_Decl::NT_attr: + case AST_Decl::NT_field: + case AST_Decl::NT_union_branch: + { + AST_Field *f = AST_Field::narrow_from_decl (this); + this->contains_wstring_ = + f->field_type ()->contains_wstring (); + break; + } + case AST_Decl::NT_typedef: + { + AST_Typedef *td = AST_Typedef::narrow_from_decl (this); + this->contains_wstring_ = + td->primitive_base_type ()->contains_wstring (); + break; + } + case AST_Decl::NT_wstring: + this->contains_wstring_ = 1; + break; + default: + this->contains_wstring_ = 0; + break; + } + } + + return this->contains_wstring_; +} + +// Non-virtual - no need to override this one. +void +AST_Decl::contains_wstring (int val) +{ + this->contains_wstring_ = val; +} + +//Narrowing methods for AST_Decl. +IMPL_NARROW_METHODS0(AST_Decl) +IMPL_NARROW_FROM_DECL(AST_Decl) + +// Narrowing methods for COMMON_Base. +IMPL_NARROW_METHODS0(COMMON_Base) diff --git a/TAO/TAO_IDL/ast/ast_enum.cpp b/TAO/TAO_IDL/ast/ast_enum.cpp new file mode 100644 index 00000000000..37837f7e5a0 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_enum.cpp @@ -0,0 +1,366 @@ +// $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 "ast_enum.h" +#include "ast_enum_val.h" +#include "ast_generator.h" +#include "ast_visitor.h" +#include "utl_identifier.h" +#include "utl_err.h" +#include "utl_indenter.h" + +ACE_RCSID (ast, + ast_enum, + "$Id$") + +AST_Enum::AST_Enum (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + AST_ConcreteType (), + UTL_Scope (), + pd_enum_counter (0), + member_count_ (-1) +{ + this->size_type (AST_Type::FIXED); +} + +AST_Enum::AST_Enum (UTL_ScopedName *n, + bool local, + bool abstract) + : COMMON_Base (local, + abstract), + AST_Decl (AST_Decl::NT_enum, + n), + AST_Type (AST_Decl::NT_enum, + n), + AST_ConcreteType (AST_Decl::NT_enum, + n), + UTL_Scope (AST_Decl::NT_enum), + pd_enum_counter (0), + member_count_ (-1) +{ + this->size_type (AST_Type::FIXED); +} + +AST_Enum::~AST_Enum (void) +{ +} + +// Return the member count. +int +AST_Enum::member_count (void) +{ + if (this->member_count_ == -1) + { + this->compute_member_count (); + } + + return this->member_count_; +} + +// Convert a numeric value to the string name +UTL_ScopedName * +AST_Enum::value_to_name (const unsigned long v) +{ + AST_EnumVal *item = 0; + AST_Decl *d = 0; + + for (UTL_ScopeActiveIterator i (this, IK_decls);!i.is_done ();i.next ()) + { + d = i.item (); + item = AST_EnumVal::narrow_from_decl (d); + + if (item->constant_value ()->ev ()->u.ulval == v) + { + return item->name (); + } + } + + return 0; +} + +// Look up an enumerator by the value of the supplied expression. +AST_EnumVal * +AST_Enum::lookup_by_value (const AST_Expression *v) +{ + AST_EnumVal *item = 0; + AST_Decl *d = 0; + + for (UTL_ScopeActiveIterator i (this, IK_decls); + !i.is_done (); + i.next ()) + { + d = i.item (); + item = AST_EnumVal::narrow_from_decl (d); + + if (item->constant_value () == v) + { + return item; + } + } + + return 0; +} + +// Compute the value to be assigned to the next enumerator. Bump the +// counter. +unsigned long +AST_Enum::next_enum_val (void) +{ + unsigned long i = pd_enum_counter++; + + return i; +} + +// Static helper functions + +// Modify scoped name of an enumval so that it is scoped inside the scope +// in which the enum is defined and not inside the enum itself +static UTL_ScopedName * +munge_name_for_enumval (UTL_ScopedName *n, + Identifier *last_component) +{ + long len = n->length (); + UTL_ScopedName *hold = n; + + // Last three components are: + // - scope in which enum is defined + // - scope for enum + // - name of enumval + + // We want to stop cdr'ing down the list when the head of the + // list is at the name for the scope in which the enum is defined. + while (len > 3) + { + len--; + n = (UTL_ScopedName *) n->tail (); + } + + UTL_IdList *id = 0; + ACE_NEW_RETURN (id, + UTL_IdList (last_component->copy (), + 0), + 0); + + n->set_tail (id); + + return hold; +} + +// Compute total number of members. +int +AST_Enum::compute_member_count (void) +{ + this->member_count_ = 0; + + // If there are elements in this scope + if (this->nmembers () > 0) + { + for (UTL_ScopeActiveIterator i (this, IK_decls); + !i.is_done (); + i.next ()) + { + // Get the next AST decl node. + ++this->member_count_; + } + } + + return 0; +} + +// Add an AST_EnumVal node to this scope. +AST_EnumVal * +AST_Enum::fe_add_enum_val (AST_EnumVal *t) +{ + AST_Decl *d = 0; + AST_EnumVal *t1 = 0; + + if (t != 0) + { + AST_Expression::AST_ExprValue *ev = + t->constant_value ()->coerce (AST_Expression::EV_ulong); + + t1 = idl_global->gen ()->create_enum_val (ev->u.ulval, + t->name ()); + + delete ev; + ev = 0; + + UTL_ScopedName *sn = + munge_name_for_enumval ((UTL_IdList *) t->name ()->copy (), + t->local_name ()); + + t->set_name (sn); + + sn = munge_name_for_enumval ((UTL_IdList *) t1->name ()->copy (), + t1->local_name ()); + + t1->set_name (sn); + } + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + // Add it to enclosing scope. + idl_global->scopes ().next_to_top ()->fe_add_enum_val (t1); + + return t; +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_Enum to the ostream o +void +AST_Enum::dump (ACE_OSTREAM_TYPE &o) +{ + AST_Decl *d = 0; + + if (this->is_local ()) + { + this->dump_i (o, "(local) "); + } + else if (this->is_abstract ()) + { + this->dump_i (o, "(abstract) "); + } + + this->dump_i (o, "enum "); + + this->local_name ()->dump (o); + + this->dump_i (o, " {\n"); + + // Must increment the iterator explicitly inside the loop. + for (UTL_ScopeActiveIterator i (this, IK_decls);!i.is_done ();) + { + d = i.item (); + d->local_name ()->dump (o); + i.next (); + + if (!i.is_done ()) + { + this->dump_i (o, ", "); + } + } + + idl_global->indent ()->skip_to (o); + + this->dump_i (o, "}"); +} + +int +AST_Enum::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_enum (this); +} + +void +AST_Enum::destroy (void) +{ + this->UTL_Scope::destroy (); + this->AST_ConcreteType::destroy (); +} + + +// Narrowing methods +IMPL_NARROW_METHODS2(AST_Enum, AST_ConcreteType, UTL_Scope) +IMPL_NARROW_FROM_DECL(AST_Enum) +IMPL_NARROW_FROM_SCOPE(AST_Enum) diff --git a/TAO/TAO_IDL/ast/ast_enum_val.cpp b/TAO/TAO_IDL/ast/ast_enum_val.cpp new file mode 100644 index 00000000000..cd8fc3a448b --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_enum_val.cpp @@ -0,0 +1,118 @@ +// $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. + +*/ + +// AST_EnumVals denote IDL enumerator declarations +// AST_EnumVals are a subclass of AST_Constant +// AST_EnumVals have no additional fields. + +#include "ast_enum_val.h" +#include "ast_visitor.h" + +ACE_RCSID (ast, + ast_enum_val, + "$Id$") + +AST_EnumVal::AST_EnumVal (void) + : COMMON_Base (), + AST_Decl (), + AST_Constant () +{ +} + +AST_EnumVal::AST_EnumVal (unsigned long v, + UTL_ScopedName *n) + : COMMON_Base (), + AST_Decl (AST_Decl::NT_enum_val, + n), + AST_Constant (AST_Expression::EV_ulong, + AST_Decl::NT_enum_val, + new AST_Expression (v), + n) +{ +} + +AST_EnumVal::~AST_EnumVal (void) +{ +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_EnumVal to the ostream o. +void +AST_EnumVal::dump (ACE_OSTREAM_TYPE &o) +{ + AST_Constant::dump (o); +} + +int +AST_EnumVal::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_enum_val (this); +} + +// Narrowing methods. +IMPL_NARROW_METHODS1(AST_EnumVal, AST_Constant) +IMPL_NARROW_FROM_DECL(AST_EnumVal) diff --git a/TAO/TAO_IDL/ast/ast_eventtype.cpp b/TAO/TAO_IDL/ast/ast_eventtype.cpp new file mode 100644 index 00000000000..7338bf6ef3d --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_eventtype.cpp @@ -0,0 +1,142 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +#include "ast_eventtype.h" +#include "ast_visitor.h" +#include "utl_identifier.h" +#include "utl_indenter.h" +#include "global_extern.h" + +ACE_RCSID (ast, + ast_eventtype, + "$Id$") + +AST_EventType::AST_EventType (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + UTL_Scope (), + AST_Interface (), + AST_ValueType () +{ +} + +AST_EventType::AST_EventType (UTL_ScopedName *n, + AST_Interface **inherits, + long n_inherits, + AST_ValueType *inherits_concrete, + AST_Interface **inherits_flat, + long n_inherits_flat, + AST_Interface **supports, + long n_supports, + AST_Interface *supports_concrete, + bool abstract, + bool truncatable, + bool custom) + : COMMON_Base (false, + abstract), + AST_Decl (AST_Decl::NT_eventtype, + n), + AST_Type (AST_Decl::NT_eventtype, + n), + UTL_Scope (AST_Decl::NT_eventtype), + AST_Interface (n, + inherits, + n_inherits, + inherits_flat, + n_inherits_flat, + false, + abstract), + AST_ValueType (n, + inherits, + n_inherits, + inherits_concrete, + inherits_flat, + n_inherits_flat, + supports, + n_supports, + supports_concrete, + abstract, + truncatable, + custom) +{ +} + +AST_EventType::~AST_EventType (void) +{ +} + +void +AST_EventType::destroy (void) +{ + this->AST_ValueType::destroy (); +} + +void +AST_EventType::dump (ACE_OSTREAM_TYPE &o) +{ + if (this->is_abstract ()) + { + this->dump_i (o, "abstract "); + } + else if (this->pd_truncatable) + { + this->dump_i (o, "truncatable "); + } + + this->dump_i (o, "eventtype "); + + this->local_name ()->dump (o); + this->dump_i (o, " "); + + if (this->pd_n_inherits > 0) + { + this->dump_i (o, ": "); + + for (long i = 0; i < this->pd_n_inherits; ++i) + { + this->pd_inherits[i]->local_name ()->dump (o); + + if (i < this->pd_n_inherits - 1) + { + this->dump_i (o, ", "); + } + } + } + + this->dump_i (o, "\n\n"); + + if (this->pd_n_supports > 0) + { + this->dump_i (o, "supports "); + + for (long i = 0; i < this->pd_n_supports; ++i) + { + this->pd_supports[i]->local_name ()->dump (o); + + if (i < this->pd_n_supports - 1) + { + this->dump_i (o, ", "); + } + } + } + + this->dump_i (o, " {\n"); + + UTL_Scope::dump (o); + idl_global->indent ()->skip_to (o); + + this->dump_i (o, "}"); +} + +int +AST_EventType::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_eventtype (this); +} + + // Narrowing. +IMPL_NARROW_METHODS1(AST_EventType, AST_ValueType) +IMPL_NARROW_FROM_DECL(AST_EventType) +IMPL_NARROW_FROM_SCOPE(AST_EventType) + diff --git a/TAO/TAO_IDL/ast/ast_eventtype_fwd.cpp b/TAO/TAO_IDL/ast/ast_eventtype_fwd.cpp new file mode 100644 index 00000000000..6bff9695525 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_eventtype_fwd.cpp @@ -0,0 +1,69 @@ +// $Id$ + +#include "ast_eventtype_fwd.h" +#include "ast_interface.h" +#include "ast_visitor.h" +#include "utl_identifier.h" + +ACE_RCSID( ast, + ast_eventtype_fwd, + "$Id$") + +AST_EventTypeFwd::AST_EventTypeFwd (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + AST_InterfaceFwd (), + AST_ValueTypeFwd () +{ +} + +AST_EventTypeFwd::AST_EventTypeFwd (AST_Interface *dummy, + UTL_ScopedName *n) + : COMMON_Base (false, + dummy->is_abstract ()), + AST_Decl (AST_Decl::NT_eventtype_fwd, + n), + AST_Type (AST_Decl::NT_eventtype_fwd, + n), + AST_InterfaceFwd (dummy, + n), + AST_ValueTypeFwd (dummy, + n) +{ +} + +AST_EventTypeFwd::~AST_EventTypeFwd (void) +{ +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_InterfaceFwd node to the ostream o. +void +AST_EventTypeFwd::dump (ACE_OSTREAM_TYPE &o) +{ + if (this->is_abstract ()) + { + this->dump_i (o, "abstract "); + } + + this->dump_i (o, "eventtype "); + + this->local_name ()->dump (o); +} + +int +AST_EventTypeFwd::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_eventtype_fwd (this); +} + +void +AST_EventTypeFwd::destroy (void) +{ +} + +// Narrowing methods. +IMPL_NARROW_METHODS1 (AST_EventTypeFwd, AST_ValueTypeFwd) +IMPL_NARROW_FROM_DECL (AST_EventTypeFwd) diff --git a/TAO/TAO_IDL/ast/ast_exception.cpp b/TAO/TAO_IDL/ast/ast_exception.cpp new file mode 100644 index 00000000000..8f03d1bda61 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_exception.cpp @@ -0,0 +1,446 @@ +// $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. + +*/ + +// AST_Exceptions denote IDL exception declarations +// AST_Exceptions are a subclass of AST_Decl (they are not types!) +// and of UTL_Scope. + +#include "ast_exception.h" +#include "ast_field.h" +#include "ast_union.h" +#include "ast_enum.h" +#include "ast_enum_val.h" +#include "ast_visitor.h" +#include "utl_err.h" +#include "utl_identifier.h" +#include "utl_indenter.h" + +ACE_RCSID (ast, + ast_exception, + "$Id$") + +AST_Exception::AST_Exception (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + AST_ConcreteType (), + UTL_Scope (), + AST_Structure () +{ +} + +AST_Exception::AST_Exception (UTL_ScopedName *n, + bool local, + bool abstract) + : COMMON_Base (local, + abstract), + AST_Decl (AST_Decl::NT_except, + n), + AST_Type (AST_Decl::NT_except, + n), + AST_ConcreteType (AST_Decl::NT_except, + n), + UTL_Scope (AST_Decl::NT_except), + AST_Structure (AST_Decl::NT_except, + n, + local, + abstract) +{ +} + +AST_Exception::~AST_Exception (void) +{ +} + +// Public operations. + +// Are we or the parameter node involved in any recursion? +bool +AST_Exception::in_recursion (ACE_Unbounded_Queue<AST_Type *> &list) +{ + // Proceed if the number of members in our scope is greater than 0. + if (this->nmembers () > 0) + { + list.enqueue_tail (this); + + // Continue until each element is visited. + for (UTL_ScopeActiveIterator i (this, IK_decls);!i.is_done ();i.next ()) + { + AST_Field *field = AST_Field::narrow_from_decl (i.item ()); + + if (field == 0) + // This will be an enum value or other legitimate non-field + // member - in any case, no recursion. + { + continue; + } + + AST_Type *type = field->field_type (); + + if (type->node_type () == AST_Decl::NT_typedef) + { + AST_Typedef *td = AST_Typedef::narrow_from_decl (type); + type = td->primitive_base_type (); + } + + if (type == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%N:%l) AST_Exception::") + ACE_TEXT ("in_recursion - ") + ACE_TEXT ("bad field type\n")), + 0); + } + + if (type->in_recursion (list)) + { + this->in_recursion_ = 1; + idl_global->recursive_type_seen_ = true; + return this->in_recursion_; + } + } + } + + // Not in recursion. + this->in_recursion_ = 0; + return this->in_recursion_; +} + +// Private operations. + +// Add this AST_Field node to the current scope. +AST_Field * +AST_Exception::fe_add_field (AST_Field *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + AST_Type *ft = t->field_type (); + UTL_ScopedName *mru = ft->last_referenced_as (); + + if (mru != 0) + { + this->add_to_referenced (ft, + false, + mru->first_component ()); + } + + this->fields_.enqueue_tail (t); + + return t; +} + +// Add this AST_Union (manifest type declaration) to the current scope. +AST_Union * +AST_Exception::fe_add_union (AST_Union *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to local types. + this->add_to_local_types (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_Structure (manifest type declaration) to the current +// scope. +AST_Structure * +AST_Exception::fe_add_structure (AST_Structure *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error2 (UTL_Error::EIDL_REDEF, + t, + this); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to local types. + this->add_to_local_types (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_Enum (manifest type declaration) to the current scope. +AST_Enum * +AST_Exception::fe_add_enum (AST_Enum *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to local types. + this->add_to_local_types (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_EnumVal (enumerator declaration) to the current scope. +// This is done to conform to the C++ scoping rules which declare +// enumerators in the enclosing scope (in addition to declaring them +// in the enum itself). +AST_EnumVal * +AST_Exception::fe_add_enum_val (AST_EnumVal *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Dump this AST_Exception node to the ostream o. +void +AST_Exception::dump (ACE_OSTREAM_TYPE &o) +{ + this->dump_i (o, "exception "); + this->local_name ()->dump (o); + this->dump_i (o, " {\n"); + UTL_Scope::dump (o); + idl_global->indent ()->skip_to (o); + this->dump_i (o, "}"); +} + +int +AST_Exception::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_exception (this); +} + +void +AST_Exception::destroy (void) +{ + this->AST_Structure::destroy (); +} + +// Narrowing methods. +IMPL_NARROW_METHODS1(AST_Exception, AST_Structure) +IMPL_NARROW_FROM_DECL(AST_Exception) +IMPL_NARROW_FROM_SCOPE(AST_Exception) diff --git a/TAO/TAO_IDL/ast/ast_expression.cpp b/TAO/TAO_IDL/ast/ast_expression.cpp new file mode 100644 index 00000000000..2591325814a --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_expression.cpp @@ -0,0 +1,3187 @@ +// $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. + +*/ + +// AST_Expression nodes denote IDL expressions used in the IDL input. + +#include "ast_expression.h" +#include "ast_constant.h" +#include "ast_visitor.h" +#include "global_extern.h" +#include "utl_err.h" +#include "utl_scope.h" +#include "utl_string.h" +#include "nr_extern.h" + +// FUZZ: disable check_for_streams_include +#include "ace/streams.h" + +ACE_RCSID (ast, + ast_expression, + "$Id$") + +// Helper function to fill out the details of where this expression +// is defined. +void +AST_Expression::fill_definition_details (void) +{ + this->pd_defined_in = idl_global->scopes ().depth () > 0 + ? idl_global->scopes().top () + : 0 ; + this->pd_line = idl_global->lineno (); + this->pd_file_name = idl_global->filename (); +} + +// Constructor(s) and destructor. + +// An AST_Expression denoting a symbolic name. +AST_Expression::AST_Expression (UTL_ScopedName *nm) + : pd_ec (EC_symbol), + pd_ev (0), + pd_v1 (0), + pd_v2 (0), + pd_n (nm), + tdef (0) +{ + this->fill_definition_details (); +} + +// An AST_Expression denoting a type coercion from another AST_Expression. +AST_Expression::AST_Expression (AST_Expression *v, + ExprType t) + : pd_ec (EC_none), + pd_ev (0), + pd_v1 (0), + pd_v2 (0), + pd_n (0), + tdef (0) +{ + this->fill_definition_details (); + + // If we are here because one string constant has + // another one as its rhs, we must copy the UTL_String + // so both can be destroyed at cleanup. + if (EV_string == t) + { + ACE_NEW (this->pd_ev, + AST_ExprValue); + + ACE_NEW (this->pd_ev->u.strval, + UTL_String (v->pd_ev->u.strval)); + + this->pd_ev->et = EV_string; + } + else if (EV_wstring == t) + { + ACE_NEW (this->pd_ev, + AST_ExprValue); + + this->pd_ev->u.wstrval = ACE::strnew (v->pd_ev->u.wstrval); + this->pd_ev->et = EV_string; + } + else + { + this->pd_ev = v->coerce (t); + + if (this->pd_ev == 0) + { + idl_global->err ()->coercion_error (v, + t); + } + + if (0 != v->pd_n) + { + this->pd_n = + dynamic_cast<UTL_ScopedName *> (v->pd_n->copy ()); + } + } +} + +// An AST_Expression denoting a binary expression combination from +// two other AST_Expressions. +AST_Expression::AST_Expression (ExprComb c, + AST_Expression *ev1, + AST_Expression *ev2) + : pd_ec (c), + pd_ev (0), + pd_v1 (ev1), + pd_v2 (ev2), + pd_n (0), + tdef (0) +{ + this->fill_definition_details (); +} + +// An AST_Expression denoting a short integer. +AST_Expression::AST_Expression (short sv) + : pd_ec (EC_none), + pd_ev (0), + pd_v1 (0), + pd_v2 (0), + pd_n (0), + tdef (0) +{ + this->fill_definition_details (); + + ACE_NEW (this->pd_ev, + AST_ExprValue); + + this->pd_ev->et = EV_short; + this->pd_ev->u.sval = sv; +} + +// An AST_Expression denoting an unsigned short integer. +AST_Expression::AST_Expression (unsigned short usv) + : pd_ec (EC_none), + pd_ev (0), + pd_v1 (0), + pd_v2 (0), + pd_n (0), + tdef (0) +{ + this->fill_definition_details (); + + ACE_NEW (this->pd_ev, + AST_ExprValue); + + this->pd_ev->et = EV_ushort; + this->pd_ev->u.usval = usv; +} + +// An AST_Expression denoting a long integer. +AST_Expression::AST_Expression (long lv) + : pd_ec (EC_none), + pd_ev (0), + pd_v1 (0), + pd_v2 (0), + pd_n (0), + tdef (0) +{ + this->fill_definition_details (); + + ACE_NEW (this->pd_ev, + AST_ExprValue); + + this->pd_ev->et = EV_long; + this->pd_ev->u.lval = lv; +} + +// An AST_Expression denoting a boolean. +AST_Expression::AST_Expression (bool b) + : pd_ec (EC_none), + pd_ev (0), + pd_v1 (0), + pd_v2 (0), + pd_n (0), + tdef (0) +{ + this->fill_definition_details (); + + ACE_NEW (this->pd_ev, + AST_ExprValue); + + this->pd_ev->et = EV_bool; + this->pd_ev->u.bval = b; +} + +// An AST_Expression denoting an unsigned long integer. +AST_Expression::AST_Expression (unsigned long ulv) + : pd_ec (EC_none), + pd_ev (0), + pd_v1 (0), + pd_v2 (0), + pd_n (0), + tdef (0) +{ + this->fill_definition_details (); + + ACE_NEW (this->pd_ev, + AST_ExprValue); + + this->pd_ev->et = EV_ulong; + this->pd_ev->u.ulval = ulv; +} + +// An AST_Expression denoting an unsigned long integer. +AST_Expression::AST_Expression (idl_uns_long ulv, + ExprType t) + : pd_ec (EC_none), + pd_ev (0), + pd_v1 (0), + pd_v2 (0), + pd_n (0), + tdef (0) +{ + this->fill_definition_details (); + + ACE_NEW (this->pd_ev, + AST_ExprValue); + + this->pd_ev->et = t; +#if defined (ACE_LACKS_LONGLONG_T) + this->pd_ev->u.ulval = ulv; +#else + this->pd_ev->u.ullval = ulv; +#endif +} + +// An AST_Expression denoting a 32-bit floating point number. +AST_Expression::AST_Expression (float fv) + : pd_ec (EC_none), + pd_ev (0), + pd_v1 (0), + pd_v2 (0), + pd_n (0), + tdef (0) +{ + this->fill_definition_details (); + + ACE_NEW (this->pd_ev, + AST_ExprValue); + + this->pd_ev->et = EV_float; + this->pd_ev->u.fval = fv; +} + +// An AST_Expression denoting a 64-bit floating point number. +AST_Expression::AST_Expression (double dv) + : pd_ec (EC_none), + pd_ev (0), + pd_v1 (0), + pd_v2 (0), + pd_n (0), + tdef (0) +{ + this->fill_definition_details (); + + ACE_NEW (this->pd_ev, + AST_ExprValue); + + this->pd_ev->et = EV_double; + this->pd_ev->u.dval = dv; +} + +// An AST_Expression denoting a character. +AST_Expression::AST_Expression (char cv) + : pd_ec (EC_none), + pd_ev (0), + pd_v1 (0), + pd_v2 (0), + pd_n (0), + tdef (0) +{ + this->fill_definition_details (); + + ACE_NEW (this->pd_ev, + AST_ExprValue); + + this->pd_ev->et = EV_char; + this->pd_ev->u.cval = cv; +} + +// An AST_Expression denoting a wide character. +AST_Expression::AST_Expression (ACE_OutputCDR::from_wchar wcv) + : pd_ec (EC_none), + pd_ev (0), + pd_v1 (0), + pd_v2 (0), + pd_n (0), + tdef (0) +{ + this->fill_definition_details (); + + ACE_NEW (this->pd_ev, + AST_ExprValue); + + this->pd_ev->et = EV_wchar; + this->pd_ev->u.wcval = wcv.val_; +} + +// An AST_Expression denoting an octet (unsigned char). +AST_Expression::AST_Expression (unsigned char ov) + : pd_ec (EC_none), + pd_ev (0), + pd_v1 (0), + pd_v2 (0), + pd_n (0), + tdef (0) +{ + this->fill_definition_details (); + + ACE_NEW (this->pd_ev, + AST_ExprValue); + + this->pd_ev->et = EV_octet; + this->pd_ev->u.oval = ov; +} + +// An AST_Expression denoting a string (char * encapsulated as a String). +AST_Expression::AST_Expression (UTL_String *sv) + : pd_ec (EC_none), + pd_ev (0), + pd_v1 (0), + pd_v2 (0), + pd_n (0), + tdef (0) +{ + this->fill_definition_details (); + + ACE_NEW (this->pd_ev, + AST_ExprValue); + + UTL_String *new_str = 0; + ACE_NEW (new_str, + UTL_String (sv)); + + this->pd_ev->u.strval = new_str; + this->pd_ev->et = EV_string; +} + +// An AST_Expression denoting a wide string. +AST_Expression::AST_Expression (char *sv) + : pd_ec (EC_none), + pd_ev (0), + pd_v1 (0), + pd_v2 (0), + pd_n (0), + tdef (0) +{ + this->fill_definition_details (); + + ACE_NEW (this->pd_ev, + AST_ExprValue); + + this->pd_ev->et = EV_wstring; + this->pd_ev->u.wstrval = sv; +} + +AST_Expression::~AST_Expression (void) +{ +} + +AST_Expression::AST_ExprValue::AST_ExprValue (void) +{ + this->u.ulval = 0UL; + this->et = AST_Expression::EV_none; +} + +// Static operations. + +// Perform the coercion from the given AST_ExprValue to the requested +// ExprType. Return an AST_ExprValue if successful, 0 if failed. +static AST_Expression::AST_ExprValue * +coerce_value (AST_Expression::AST_ExprValue *ev, + AST_Expression::ExprType t) +{ + if (ev == 0) + { + return 0; + } + + switch (t) + { + case AST_Expression::EV_short: + switch (ev->et) + { + case AST_Expression::EV_short: + return ev; + case AST_Expression::EV_ushort: + if (ev->u.usval > (unsigned short) ACE_INT16_MAX) + { + return 0; + } + + ev->u.sval = (short) ev->u.usval; + ev->et = AST_Expression::EV_short; + return ev; + case AST_Expression::EV_long: + if (ev->u.lval > (long) ACE_INT16_MAX + || ev->u.lval < (long) ACE_INT16_MIN) + { + return 0; + } + + ev->u.sval = (short) ev->u.lval; + ev->et = AST_Expression::EV_short; + return ev; + case AST_Expression::EV_ulong: + if (ev->u.ulval > (unsigned long) ACE_INT16_MAX) + { + return 0; + } + + ev->u.sval = (short) ev->u.ulval; + ev->et = AST_Expression::EV_short; + return ev; + case AST_Expression::EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) + if (ev->u.llval > (ACE_CDR::LongLong) ACE_INT16_MAX + || ev->u.llval < (ACE_CDR::LongLong) ACE_INT16_MIN) + { + return 0; + } + + ev->u.sval = (short) ev->u.llval; + ev->et = AST_Expression::EV_short; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) + if ((ev->u.ullval & ACE_INT16_MAX) != ev->u.ullval) + { + return 0; + } + + ev->u.sval = (short) ev->u.ullval; + ev->et = AST_Expression::EV_short; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_bool: + ev->u.sval = (short) ev->u.bval; + ev->et = AST_Expression::EV_short; + return ev; + case AST_Expression::EV_float: + if (ev->u.fval > (float) ACE_INT16_MAX + || ev->u.fval < (float) ACE_INT16_MIN) + { + return 0; + } + + ev->u.sval = (short) ev->u.fval; + ev->et = AST_Expression::EV_short; + return ev; + case AST_Expression::EV_double: + if (ev->u.dval > (double) ACE_INT16_MAX + || ev->u.dval < (double) ACE_INT16_MIN) + { + return 0; + } + + ev->u.sval = (short) ev->u.dval; + ev->et = AST_Expression::EV_short; + return ev; + case AST_Expression::EV_char: + ev->u.sval = (short) ev->u.cval; + ev->et = AST_Expression::EV_short; + return ev; + case AST_Expression::EV_wchar: + if (ev->u.wcval > (ACE_CDR::WChar) ACE_INT16_MAX) + { + return 0; + } + + ev->u.sval = (short) ev->u.wcval; + ev->et = AST_Expression::EV_short; + return ev; + case AST_Expression::EV_octet: + ev->u.sval = (short) ev->u.oval; + ev->et = AST_Expression::EV_short; + return ev; + case AST_Expression::EV_longdouble: + case AST_Expression::EV_string: + case AST_Expression::EV_wstring: + case AST_Expression::EV_enum: + case AST_Expression::EV_void: + case AST_Expression::EV_none: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + return 0; + } + case AST_Expression::EV_ushort: + switch (ev->et) + { + case AST_Expression::EV_short: + if (ev->u.sval < 0) + { + return 0; + } + + ev->u.usval = (unsigned short) ev->u.sval; + ev->et = AST_Expression::EV_ushort; + return ev; + case AST_Expression::EV_ushort: + return ev; + case AST_Expression::EV_long: + if (ev->u.lval > (long) ACE_UINT16_MAX + || ev->u.lval < 0) + { + return 0; + } + + ev->u.usval = (unsigned short) ev->u.lval; + ev->et = AST_Expression::EV_ushort; + return ev; + case AST_Expression::EV_ulong: + if (ev->u.ulval > (unsigned long) ACE_UINT16_MAX) + { + return 0; + } + + ev->u.usval = (unsigned short) ev->u.ulval; + ev->et = AST_Expression::EV_ushort; + return ev; + case AST_Expression::EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) + if (ev->u.llval > (ACE_CDR::LongLong) ACE_UINT16_MAX + || ev->u.llval < 0) + { + return 0; + } + + ev->u.usval = (unsigned short) ev->u.llval; + ev->et = AST_Expression::EV_ushort; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) + if ((ev->u.ullval & ACE_UINT16_MAX) != ev->u.ullval) + { + return 0; + } + + ev->u.usval = (unsigned short) ev->u.ullval; + ev->et = AST_Expression::EV_ushort; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_bool: + ev->u.usval = (unsigned short) ev->u.bval; + ev->et = AST_Expression::EV_ushort; + return ev; + case AST_Expression::EV_float: + if (ev->u.fval < 0.0 + || ev->u.fval > (float) ACE_UINT16_MAX) + { + return 0; + } + + ev->u.usval = (unsigned short) ev->u.fval; + ev->et = AST_Expression::EV_ushort; + return ev; + case AST_Expression::EV_double: + if (ev->u.dval < 0.0 + || ev->u.dval > (double) ACE_UINT16_MAX) + { + return 0; + } + + ev->u.usval = (unsigned short) ev->u.dval; + ev->et = AST_Expression::EV_ushort; + return ev; + case AST_Expression::EV_char: + if ((signed char) ev->u.cval < 0) + { + return 0; + } + + ev->u.usval = (unsigned short) ev->u.cval; + ev->et = AST_Expression::EV_ushort; + return ev; + case AST_Expression::EV_wchar: + ev->u.usval = (unsigned short) ev->u.wcval; + ev->et = AST_Expression::EV_ushort; + return ev; + case AST_Expression::EV_octet: + ev->u.usval = (unsigned short) ev->u.oval; + ev->et = AST_Expression::EV_ushort; + return ev; + case AST_Expression::EV_longdouble: + case AST_Expression::EV_wstring: + case AST_Expression::EV_string: + case AST_Expression::EV_enum: + case AST_Expression::EV_void: + case AST_Expression::EV_none: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + return 0; + } + case AST_Expression::EV_long: + switch (ev->et) + { + case AST_Expression::EV_short: + ev->u.lval = (long) ev->u.sval; + ev->et = AST_Expression::EV_long; + return ev; + case AST_Expression::EV_ushort: + ev->u.lval = (long) ev->u.usval; + ev->et = AST_Expression::EV_long; + return ev; + case AST_Expression::EV_long: + return ev; + case AST_Expression::EV_ulong: + if (ev->u.ulval > (unsigned long) ACE_INT32_MAX) + { + return 0; + } + + ev->u.lval = (long) ev->u.ulval; + ev->et = AST_Expression::EV_long; + return ev; + case AST_Expression::EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) + if (ev->u.llval > (ACE_CDR::LongLong) ACE_INT32_MAX + || ev->u.llval < (ACE_CDR::LongLong) ACE_INT32_MIN) + { + return 0; + } + ev->u.lval = (long) ev->u.llval; + ev->et = AST_Expression::EV_long; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) + if ((ev->u.ullval & ACE_INT32_MAX) != ev->u.ullval) + { + return 0; + } + + ev->u.lval = (long) ev->u.ullval; + ev->et = AST_Expression::EV_long; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_bool: + ev->u.lval = (long) ev->u.bval; + ev->et = AST_Expression::EV_long; + return ev; + case AST_Expression::EV_float: + if (ev->u.fval > (float) LONG_MAX + || ev->u.fval < (float) ACE_INT32_MIN) + { + return 0; + } + + ev->u.lval = (long) ev->u.fval; + ev->et = AST_Expression::EV_long; + return ev; + case AST_Expression::EV_double: + if (ev->u.dval > (double) LONG_MAX + || ev->u.dval < (double) ACE_INT32_MIN) + { + return 0; + } + + ev->u.lval = (long) ev->u.dval; + ev->et = AST_Expression::EV_long; + return ev; + case AST_Expression::EV_char: + ev->u.lval = (long) ev->u.cval; + ev->et = AST_Expression::EV_long; + return ev; + case AST_Expression::EV_wchar: + ev->u.lval = (long) ev->u.wcval; + ev->et = AST_Expression::EV_long; + return ev; + case AST_Expression::EV_octet: + ev->u.lval = (long) ev->u.oval; + ev->et = AST_Expression::EV_long; + return ev; + case AST_Expression::EV_longdouble: + case AST_Expression::EV_wstring: + case AST_Expression::EV_string: + case AST_Expression::EV_enum: + case AST_Expression::EV_void: + case AST_Expression::EV_none: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + return 0; + } + case AST_Expression::EV_ulong: + switch (ev->et) + { + case AST_Expression::EV_short: + if (ev->u.sval < 0) + { + return 0; + } + + ev->u.ulval = (unsigned long) ev->u.sval; + ev->et = AST_Expression::EV_ulong; + return ev; + case AST_Expression::EV_ushort: + ev->u.ulval = (unsigned long) ev->u.usval; + ev->et = AST_Expression::EV_ulong; + return ev; + case AST_Expression::EV_long: + if (ev->u.lval < 0) + { + return 0; + } + + ev->u.ulval = (unsigned long) ev->u.lval; + ev->et = AST_Expression::EV_ulong; + return ev; + case AST_Expression::EV_ulong: + return ev; + case AST_Expression::EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) + if (ev->u.llval > (ACE_CDR::LongLong) ACE_UINT32_MAX + || ev->u.llval < 0) + { + return 0; + } + + ev->u.ulval = (unsigned long) ev->u.llval; + ev->et = AST_Expression::EV_ulong; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return NULL; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) + if ((ev->u.ullval & ACE_UINT32_MAX) != ev->u.ullval) + { + return 0; + } + ev->u.ulval = (unsigned long) ev->u.ullval; + ev->et = AST_Expression::EV_ulong; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_bool: + ev->u.ulval = (unsigned long) ev->u.bval; + ev->et = AST_Expression::EV_ulong; + return ev; + case AST_Expression::EV_float: + if (ev->u.fval < 0.0 + || ev->u.fval > (float) ACE_UINT32_MAX) + { + return 0; + } + + ev->u.ulval = (unsigned long) ev->u.fval; + ev->et = AST_Expression::EV_ulong; + return ev; + case AST_Expression::EV_double: + if (ev->u.dval < 0.0 + || ev->u.dval > (double) ACE_UINT32_MAX) + { + return 0; + } + + ev->u.ulval = (unsigned long) ev->u.dval; + ev->et = AST_Expression::EV_ulong; + return ev; + case AST_Expression::EV_char: + if ((signed char) ev->u.cval < 0) + { + return 0; + } + + ev->u.ulval = (unsigned long) ev->u.cval; + ev->et = AST_Expression::EV_ulong; + return ev; + case AST_Expression::EV_wchar: + ev->u.ulval = (unsigned long) ev->u.wcval; + ev->et = AST_Expression::EV_ulong; + return ev; + case AST_Expression::EV_octet: + ev->u.ulval = (unsigned long) ev->u.oval; + ev->et = AST_Expression::EV_ulong; + return ev; + case AST_Expression::EV_longdouble: + case AST_Expression::EV_wstring: + case AST_Expression::EV_string: + case AST_Expression::EV_enum: + case AST_Expression::EV_void: + case AST_Expression::EV_none: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + return 0; + } + case AST_Expression::EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) + switch (ev->et) + { + case AST_Expression::EV_short: + ev->u.llval = (ACE_CDR::LongLong) ev->u.sval; + ev->et = AST_Expression::EV_longlong; + return ev; + case AST_Expression::EV_ushort: + ev->u.llval = (ACE_CDR::LongLong) ev->u.usval; + ev->et = AST_Expression::EV_longlong; + return ev; + case AST_Expression::EV_long: + ev->u.llval = (ACE_CDR::LongLong) ev->u.lval; + ev->et = AST_Expression::EV_longlong; + return ev; + case AST_Expression::EV_ulong: + ev->u.llval = (ACE_CDR::LongLong) ev->u.ulval; + ev->et = AST_Expression::EV_longlong; + return ev; + case AST_Expression::EV_longlong: + return ev; + case AST_Expression::EV_ulonglong: + if (ev->u.ullval > ACE_INT64_MAX) + { + return 0; + } + + ev->u.llval = (ACE_CDR::LongLong) ev->u.ullval; + ev->et = AST_Expression::EV_longlong; + return ev; + case AST_Expression::EV_bool: + ev->u.llval = (ACE_CDR::LongLong) ev->u.bval; + ev->et = AST_Expression::EV_longlong; + return ev; + case AST_Expression::EV_float: + if (ev->u.fval > (float) ACE_INT64_MAX + || ev->u.fval < (float) ACE_INT64_MIN) + { + return 0; + } + + ev->u.llval = (ACE_CDR::LongLong) ev->u.fval; + ev->et = AST_Expression::EV_longlong; + return ev; + case AST_Expression::EV_double: + if (ev->u.dval > (double) ACE_INT64_MAX + || ev->u.dval < (double) ACE_INT64_MIN) + { + return 0; + } + + ev->u.llval = (ACE_CDR::LongLong) ev->u.dval; + ev->et = AST_Expression::EV_longlong; + return ev; + case AST_Expression::EV_char: + ev->u.llval = (ACE_CDR::LongLong) ev->u.cval; + ev->et = AST_Expression::EV_longlong; + return ev; + case AST_Expression::EV_wchar: + ev->u.llval = (ACE_CDR::LongLong) ev->u.wcval; + ev->et = AST_Expression::EV_longlong; + return ev; + case AST_Expression::EV_octet: + ev->u.llval = (ACE_CDR::LongLong) ev->u.oval; + ev->et = AST_Expression::EV_longlong; + return ev; + case AST_Expression::EV_longdouble: + case AST_Expression::EV_wstring: + case AST_Expression::EV_string: + case AST_Expression::EV_enum: + case AST_Expression::EV_void: + case AST_Expression::EV_none: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + return 0; + } +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) + switch (ev->et) + { + case AST_Expression::EV_short: + if (ev->u.sval < 0) + { + return 0; + } + + ev->u.ullval = ev->u.sval; + ev->et = AST_Expression::EV_ulonglong; + return ev; + case AST_Expression::EV_ushort: + ev->u.ullval = ev->u.usval; + ev->et = AST_Expression::EV_ulonglong; + return ev; + case AST_Expression::EV_long: + if (ev->u.lval < 0) + { + return 0; + } + + ev->u.ullval = ev->u.lval; + ev->et = AST_Expression::EV_ulonglong; + return ev; + case AST_Expression::EV_ulong: + ev->u.ullval = ev->u.ulval; + ev->et = AST_Expression::EV_ulonglong; + return ev; + case AST_Expression::EV_longlong: + if (ev->u.llval < 0) + { + return 0; + } + + ev->u.ullval = (ACE_CDR::LongLong) ev->u.llval; + ev->et = AST_Expression::EV_ulonglong; + return ev; + case AST_Expression::EV_ulonglong: + return ev; + case AST_Expression::EV_bool: + ev->u.ullval = ev->u.bval; + ev->et = AST_Expression::EV_ulonglong; + return ev; + case AST_Expression::EV_float: +#if defined (ACE_LACKS_UNSIGNEDLONGLONG_T) + if (ev->u.fval < 0.0 + || ev->u.fval > (float) ACE_INT64_MAX) + { + return 0; + } + + ev->u.ullval = static_cast<ACE_UINT32> (ev->u.fval); +#else + if (ev->u.fval < 0.0 + || ev->u.fval > (float) ACE_UINT64_MAX) + { + return 0; + } + + ev->u.ullval = static_cast<ACE_UINT64> (ev->u.fval); +#endif + + ev->et = AST_Expression::EV_ulonglong; + return ev; + case AST_Expression::EV_double: +#if defined (ACE_LACKS_UNSIGNEDLONGLONG_T) + if (ev->u.dval < 0.0 + || ev->u.dval > (double) ACE_INT64_MAX) + { + return 0; + } + + ev->u.ullval = static_cast<ACE_UINT32> (ev->u.dval); +#else + if (ev->u.dval < 0.0 + || ev->u.dval > (double) ACE_UINT64_MAX) + { + return 0; + } + + ev->u.ullval = static_cast<ACE_UINT64> (ev->u.dval); +#endif + + ev->et = AST_Expression::EV_ulonglong; + return ev; + case AST_Expression::EV_char: + if ((signed char) ev->u.cval < 0) + { + return 0; + } + + ev->u.ullval = ev->u.cval; + ev->et = AST_Expression::EV_ulonglong; + return ev; + case AST_Expression::EV_wchar: + ev->u.ullval = ev->u.wcval; + ev->et = AST_Expression::EV_ulonglong; + return ev; + case AST_Expression::EV_octet: + ev->u.ullval = ev->u.oval; + ev->et = AST_Expression::EV_ulonglong; + return ev; + case AST_Expression::EV_longdouble: + case AST_Expression::EV_wstring: + case AST_Expression::EV_string: + case AST_Expression::EV_enum: + case AST_Expression::EV_void: + case AST_Expression::EV_none: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + return 0; + } +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_bool: + switch (ev->et) + { + case AST_Expression::EV_short: + ev->u.bval = (ev->u.sval == 0) ? false : true; + ev->et = AST_Expression::EV_bool; + return ev; + case AST_Expression::EV_ushort: + ev->u.bval = (ev->u.usval == 0) ? false : true; + ev->et = AST_Expression::EV_bool; + return ev; + case AST_Expression::EV_long: + ev->u.bval = (ev->u.lval == 0) ? false : true; + ev->et = AST_Expression::EV_bool; + return ev; + case AST_Expression::EV_ulong: + ev->u.bval = (ev->u.ulval == 0) ? false : true; + ev->et = AST_Expression::EV_bool; + return ev; + case AST_Expression::EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) + ev->u.bval = (ev->u.llval == 0) ? false : true; + ev->et = AST_Expression::EV_bool; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) + ev->u.bval = (ev->u.ullval == 0) ? false : true; + ev->et = AST_Expression::EV_bool; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_bool: + return ev; + case AST_Expression::EV_float: + ev->u.bval = (ev->u.fval == 0.0) ? false : true; + ev->et = AST_Expression::EV_bool; + return ev; + case AST_Expression::EV_double: + ev->u.bval = (ev->u.dval == 0.0) ? false : true; + ev->et = AST_Expression::EV_bool; + return ev; + case AST_Expression::EV_char: + ev->u.bval = (ev->u.cval == 0) ? false : true; + ev->et = AST_Expression::EV_bool; + return ev; + case AST_Expression::EV_wchar: + ev->u.bval = (ev->u.wcval == 0) ? false : true; + ev->et = AST_Expression::EV_bool; + return ev; + case AST_Expression::EV_octet: + ev->u.bval = (ev->u.oval == 0) ? false : true; + ev->et = AST_Expression::EV_bool; + return ev; + case AST_Expression::EV_longdouble: + case AST_Expression::EV_wstring: + case AST_Expression::EV_string: + case AST_Expression::EV_enum: + case AST_Expression::EV_void: + case AST_Expression::EV_none: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + return 0; + } + case AST_Expression::EV_float: + switch (ev->et) + { + case AST_Expression::EV_short: + ev->u.fval = (float) ev->u.sval; + ev->et = AST_Expression::EV_float; + return ev; + case AST_Expression::EV_ushort: + ev->u.fval = (float) ev->u.usval; + ev->et = AST_Expression::EV_float; + return ev; + case AST_Expression::EV_long: + ev->u.fval = (float) ev->u.lval; + ev->et = AST_Expression::EV_float; + return ev; + case AST_Expression::EV_ulong: + ev->u.fval = (float) ev->u.ulval; + ev->et = AST_Expression::EV_float; + return ev; + case AST_Expression::EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) + if (ev->u.llval > FLT_MAX + || ev->u.llval < -(ACE_FLT_MAX)) + { + return 0; + } + ev->u.fval = (float) ev->u.llval; + ev->et = AST_Expression::EV_float; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) + ev->u.fval = (float) ((ACE_CDR::LongLong) ev->u.ullval); + ev->et = AST_Expression::EV_float; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_bool: + ev->u.fval = (float) ((ev->u.bval == true) ? 1.0 : 0.0); + ev->et = AST_Expression::EV_float; + return ev; + case AST_Expression::EV_float: + return ev; + case AST_Expression::EV_double: + if (ev->u.dval > ACE_FLT_MAX + || ev->u.dval < -(ACE_FLT_MAX)) + { + return 0; + } + + ev->u.fval = (float) ev->u.dval; + ev->et = AST_Expression::EV_float; + return ev; + case AST_Expression::EV_char: + ev->u.fval = (float) ev->u.cval; + ev->et = AST_Expression::EV_float; + return ev; + case AST_Expression::EV_wchar: + ev->u.fval = (float) ev->u.wcval; + ev->et = AST_Expression::EV_float; + return ev; + case AST_Expression::EV_octet: + ev->u.fval = (float) ev->u.oval; + ev->et = AST_Expression::EV_float; + return ev; + case AST_Expression::EV_longdouble: + case AST_Expression::EV_wstring: + case AST_Expression::EV_string: + case AST_Expression::EV_enum: + case AST_Expression::EV_void: + case AST_Expression::EV_none: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + return 0; + } + case AST_Expression::EV_double: + switch (ev->et) + { + case AST_Expression::EV_short: + ev->u.dval = (double) ev->u.sval; + ev->et = AST_Expression::EV_double; + return ev; + case AST_Expression::EV_ushort: + ev->u.dval = (double) ev->u.usval; + ev->et = AST_Expression::EV_double; + return ev; + case AST_Expression::EV_long: + ev->u.dval = (double) ev->u.lval; + ev->et = AST_Expression::EV_double; + return ev; + case AST_Expression::EV_ulong: + ev->u.dval = (double) ev->u.ulval; + ev->et = AST_Expression::EV_double; + return ev; + case AST_Expression::EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) + ev->u.dval = (double) ev->u.llval; + ev->et = AST_Expression::EV_double; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) + // Some compilers don't implement unsigned 64-bit to double + // conversions, so we are stuck with the signed 64-bit max value. + if (ev->u.ullval > ACE_INT64_MAX) + { + return 0; + } + + ev->u.dval = (double) ((ACE_CDR::LongLong) ev->u.ullval); + ev->et = AST_Expression::EV_double; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return NULL; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_bool: + ev->u.dval = (ev->u.bval == true) ? 1.0 : 0.0; + ev->et = AST_Expression::EV_double; + return ev; + case AST_Expression::EV_float: + ev->u.dval = (double) ev->u.fval; + ev->et = AST_Expression::EV_double; + return ev; + case AST_Expression::EV_double: + return ev; + case AST_Expression::EV_char: + ev->u.dval = (double) ev->u.cval; + ev->et = AST_Expression::EV_double; + return ev; + case AST_Expression::EV_wchar: + ev->u.dval = (double) ev->u.wcval; + ev->et = AST_Expression::EV_double; + return ev; + case AST_Expression::EV_octet: + ev->u.dval = (double) ev->u.oval; + ev->et = AST_Expression::EV_double; + return ev; + case AST_Expression::EV_longdouble: + case AST_Expression::EV_wstring: + case AST_Expression::EV_string: + case AST_Expression::EV_enum: + case AST_Expression::EV_void: + case AST_Expression::EV_none: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + return 0; + } + case AST_Expression::EV_char: + switch (ev->et) + { + case AST_Expression::EV_short: + if (ev->u.sval > (short) ACE_CHAR_MAX + || ev->u.sval < (short) ACE_CHAR_MIN) + { + return 0; + } + + ev->u.cval = (char) ev->u.sval; + ev->et = AST_Expression::EV_char; + return ev; + case AST_Expression::EV_ushort: + if (ev->u.usval > (unsigned short) ACE_CHAR_MAX) + { + return 0; + } + + ev->u.cval = (char) ev->u.usval; + ev->et = AST_Expression::EV_char; + return ev; + case AST_Expression::EV_long: + if (ev->u.lval > (long) ACE_CHAR_MAX + || ev->u.lval < (long) ACE_CHAR_MIN) + { + return 0; + } + + ev->u.cval = (char) ev->u.lval; + ev->et = AST_Expression::EV_char; + return ev; + case AST_Expression::EV_ulong: + if (ev->u.ulval > (unsigned long) ACE_CHAR_MAX) + { + return 0; + } + + ev->u.cval = (char) ev->u.ulval; + ev->et = AST_Expression::EV_char; + return ev; + case AST_Expression::EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) + if (ev->u.llval > (ACE_CDR::LongLong) ACE_CHAR_MAX + || ev->u.llval < (ACE_CDR::LongLong) ACE_CHAR_MIN) + { + return 0; + } + + ev->u.cval = (char) ev->u.llval; + ev->et = AST_Expression::EV_char; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) + if (( ev->u.ullval & ACE_CHAR_MAX) != ev->u.ullval) + { + return 0; + } + + ev->u.cval = (char) ev->u.ullval; + ev->et = AST_Expression::EV_char; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_bool: + ev->u.cval = (char) ev->u.bval; + ev->et = AST_Expression::EV_char; + return ev; + case AST_Expression::EV_float: + if (ev->u.fval > (float) ACE_CHAR_MAX + || ev->u.fval < (float) ACE_CHAR_MIN) + { + return 0; + } + + ev->u.cval = (char) ev->u.fval; + ev->et = AST_Expression::EV_char; + return ev; + case AST_Expression::EV_double: + if (ev->u.dval > (double) ACE_CHAR_MAX + || ev->u.dval < (double) ACE_CHAR_MIN) + { + return 0; + } + + ev->u.cval = (char) ev->u.dval; + ev->et = AST_Expression::EV_char; + return ev; + case AST_Expression::EV_char: + return ev; + case AST_Expression::EV_wchar: + if (ev->u.wcval > (ACE_CDR::WChar) ACE_CHAR_MAX) + { + return 0; + } + + ev->u.cval = (char) ev->u.wcval; + ev->et = AST_Expression::EV_char; + return ev; + case AST_Expression::EV_octet: + if (ev->u.oval > (unsigned char) ACE_CHAR_MAX) + { + return 0; + } + + ev->u.cval = (char) ev->u.oval; + ev->et = AST_Expression::EV_char; + return ev; + case AST_Expression::EV_longdouble: + case AST_Expression::EV_wstring: + case AST_Expression::EV_string: + case AST_Expression::EV_enum: + case AST_Expression::EV_void: + case AST_Expression::EV_none: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + return 0; + } + case AST_Expression::EV_wchar: + switch (ev->et) + { + case AST_Expression::EV_short: + if (ev->u.sval < 0) + { + return 0; + } + + ev->u.wcval = (ACE_CDR::WChar) ev->u.sval; + ev->et = AST_Expression::EV_wchar; + return ev; + case AST_Expression::EV_ushort: + ev->u.wcval = (ACE_CDR::WChar) ev->u.usval; + ev->et = AST_Expression::EV_char; + return ev; + case AST_Expression::EV_long: + if (ev->u.lval < 0 + || ev->u.lval > ACE_WCHAR_MAX) + { + return 0; + } + + ev->u.wcval = (ACE_CDR::WChar) ev->u.lval; + ev->et = AST_Expression::EV_wchar; + return ev; + case AST_Expression::EV_ulong: + if (ev->u.ulval > ACE_WCHAR_MAX) + { + return 0; + } + + ev->u.wcval = (ACE_CDR::WChar) ev->u.ulval; + ev->et = AST_Expression::EV_wchar; + return ev; + case AST_Expression::EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) + if (ev->u.llval > (ACE_CDR::LongLong) ACE_WCHAR_MAX + || ev->u.llval < 0) + { + return 0; + } + + ev->u.wcval = (ACE_CDR::WChar) ev->u.llval; + ev->et = AST_Expression::EV_wchar; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) + if ((ev->u.ullval & ACE_WCHAR_MAX) != ev->u.ullval ) + { + return 0; + } + + ev->u.wcval = (ACE_CDR::WChar) ev->u.ullval; + ev->et = AST_Expression::EV_wchar; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_bool: + ev->u.wcval = (ACE_CDR::WChar) ev->u.bval; + ev->et = AST_Expression::EV_wchar; + return ev; + case AST_Expression::EV_float: + if (ev->u.fval > (float) ACE_WCHAR_MAX + || ev->u.fval < 0) + { + return 0; + } + + ev->u.wcval = (ACE_CDR::WChar) ev->u.fval; + ev->et = AST_Expression::EV_wchar; + return ev; + case AST_Expression::EV_double: + if (ev->u.dval > (double) ACE_WCHAR_MAX + || ev->u.dval < 0) + { + return 0; + } + + ev->u.wcval = (ACE_CDR::WChar) ev->u.dval; + ev->et = AST_Expression::EV_wchar; + return ev; + case AST_Expression::EV_char: + if ((signed char) ev->u.cval < 0) + { + return 0; + } + + ev->u.wcval = (ACE_CDR::WChar) ev->u.cval; + ev->et = AST_Expression::EV_wchar; + return ev; + case AST_Expression::EV_wchar: + return ev; + case AST_Expression::EV_octet: + ev->u.wcval = (ACE_CDR::WChar) ev->u.oval; + ev->et = AST_Expression::EV_wchar; + return ev; + case AST_Expression::EV_longdouble: + case AST_Expression::EV_wstring: + case AST_Expression::EV_string: + case AST_Expression::EV_enum: + case AST_Expression::EV_void: + case AST_Expression::EV_none: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + return 0; + } + case AST_Expression::EV_octet: + switch (ev->et) + { + case AST_Expression::EV_short: + if (ev->u.sval < 0 + || ev->u.sval > (short) ACE_OCTET_MAX) + { + return 0; + } + + ev->u.oval = (unsigned char) ev->u.sval; + ev->et = AST_Expression::EV_octet; + return ev; + case AST_Expression::EV_ushort: + if (ev->u.usval > (unsigned short) ACE_OCTET_MAX) + { + return 0; + } + + ev->u.oval = (unsigned char) ev->u.usval; + ev->et = AST_Expression::EV_octet; + return ev; + case AST_Expression::EV_long: + if (ev->u.lval < 0 + || ev->u.lval > (long) ACE_OCTET_MAX) + { + return 0; + } + + ev->u.oval = (unsigned char) ev->u.lval; + ev->et = AST_Expression::EV_octet; + return ev; + case AST_Expression::EV_ulong: + if (ev->u.ulval > (unsigned long) ACE_OCTET_MAX) + { + return 0; + } + + ev->u.oval = (unsigned char) ev->u.ulval; + ev->et = AST_Expression::EV_octet; + return ev; + case AST_Expression::EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) + if (ev->u.llval < 0 + || ev->u.llval > (ACE_CDR::LongLong) ACE_OCTET_MAX) + { + return 0; + } + + ev->u.oval = (unsigned char) ev->u.llval; + ev->et = AST_Expression::EV_octet; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) + if ((ev->u.ullval & ACE_OCTET_MAX) != ev->u.ullval) + { + return 0; + } + + ev->u.oval = (unsigned char) ev->u.ullval; + ev->et = AST_Expression::EV_octet; + return ev; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EV_bool: + ev->u.oval = (unsigned char) ((ev->u.bval == false) ? 1 : 0); + ev->et = AST_Expression::EV_octet; + return ev; + case AST_Expression::EV_float: + if (ev->u.fval < 0.0 + || ev->u.fval > (float) ACE_OCTET_MAX) + { + return 0; + } + + ev->u.oval = (unsigned char) ev->u.fval; + ev->et = AST_Expression::EV_octet; + return ev; + case AST_Expression::EV_double: + if (ev->u.dval < 0.0 + || ev->u.dval > (double) ACE_OCTET_MAX) + { + return 0; + } + + ev->u.oval = (unsigned char) ev->u.dval; + ev->et = AST_Expression::EV_octet; + return ev; + case AST_Expression::EV_char: + if ((signed char) ev->u.cval < 0) + { + return 0; + } + + ev->u.oval = (unsigned char) ev->u.cval; + ev->et = AST_Expression::EV_octet; + return ev; + case AST_Expression::EV_wchar: + if (ev->u.wcval > (ACE_CDR::WChar) ACE_OCTET_MAX) + { + return 0; + } + + ev->u.oval = (unsigned char) ev->u.wcval; + ev->et = AST_Expression::EV_octet; + return ev; + case AST_Expression::EV_octet: + return ev; + case AST_Expression::EV_longdouble: + case AST_Expression::EV_wstring: + case AST_Expression::EV_string: + case AST_Expression::EV_enum: + case AST_Expression::EV_void: + case AST_Expression::EV_none: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + return 0; + } + case AST_Expression::EV_enum: + switch (ev->et) + { + case AST_Expression::EV_enum: + case AST_Expression::EV_ulong: + return ev; + default: + return 0; + } + case AST_Expression::EV_void: + switch (ev->et) + { + case AST_Expression::EV_void: + return ev; + default: + return 0; + } + case AST_Expression::EV_none: + return 0; + case AST_Expression::EV_string: + switch (ev->et) + { + case AST_Expression::EV_string: + return ev; + default: + return 0; + } + case AST_Expression::EV_longdouble: + case AST_Expression::EV_wstring: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + return 0; + } + + return 0; +} + +// Integer literals may not be assigned to floating point constants, +// and vice versa. +static bool +incompatible_types (AST_Expression::ExprType t1, + AST_Expression::ExprType t2) +{ + switch (t1) + { + case AST_Expression::EV_short: + case AST_Expression::EV_ushort: + case AST_Expression::EV_long: + case AST_Expression::EV_ulong: + case AST_Expression::EV_longlong: + case AST_Expression::EV_ulonglong: + case AST_Expression::EV_octet: + case AST_Expression::EV_bool: + switch (t2) + { + case AST_Expression::EV_short: + case AST_Expression::EV_ushort: + case AST_Expression::EV_long: + case AST_Expression::EV_ulong: + case AST_Expression::EV_longlong: + case AST_Expression::EV_ulonglong: + case AST_Expression::EV_octet: + case AST_Expression::EV_bool: + return 0; + default: + return 1; + } + case AST_Expression::EV_float: + case AST_Expression::EV_double: + case AST_Expression::EV_longdouble: + switch (t2) + { + case AST_Expression::EV_float: + case AST_Expression::EV_double: + case AST_Expression::EV_longdouble: + return 0; + default: + return 1; + } + case AST_Expression::EV_char: + case AST_Expression::EV_wchar: + case AST_Expression::EV_string: + case AST_Expression::EV_wstring: + case AST_Expression::EV_enum: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + case AST_Expression::EV_void: + case AST_Expression::EV_none: + default: + return 0; + } +} + +// Evaluate the expression wrt the evaluation kind requested. Supported +// evaluation kinds are +// - EK_const: The expression must evaluate to a constant +// - EK_positive_int: The expression must further evaluate to a +// positive integer + +// @@(JP) This just maps one enum to another. It's a temporary fix, +// but AST_Expression::EvalKind should go eventually. +static AST_Expression::AST_ExprValue * +eval_kind (AST_Expression::AST_ExprValue *ev, AST_Expression::EvalKind ek) +{ + // Make a copy to simplify the memory management logic. + AST_Expression::AST_ExprValue *newval = 0; + ACE_NEW_RETURN (newval, + AST_Expression::AST_ExprValue, + 0); + + if (ev != 0) + { + *newval = *ev; + } + + AST_Expression::AST_ExprValue *retval = 0; + + switch (ek) + { + case AST_Expression::EK_const: + retval = newval; + break; + case AST_Expression::EK_positive_int: + retval = coerce_value (newval, AST_Expression::EV_ulong); + break; + case AST_Expression::EK_short: + retval = coerce_value (newval, AST_Expression::EV_short); + break; + case AST_Expression::EK_ushort: + retval = coerce_value (newval, AST_Expression::EV_ushort); + break; + case AST_Expression::EK_long: + retval = coerce_value (newval, AST_Expression::EV_long); + break; + case AST_Expression::EK_ulong: + retval = coerce_value (newval, AST_Expression::EV_ulong); + break; +#if ! defined (ACE_LACKS_LONGLONG_T) + case AST_Expression::EK_longlong: + retval = coerce_value (newval, AST_Expression::EV_longlong); + break; + case AST_Expression::EK_ulonglong: + retval = coerce_value (newval, AST_Expression::EV_ulonglong); + break; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case AST_Expression::EK_octet: + retval = coerce_value (newval, AST_Expression::EV_octet); + break; + case AST_Expression::EK_bool: + retval = coerce_value (newval, AST_Expression::EV_bool); + break; + default: + break; + } + + // Sometimes the call above to coerce_value() will return an + // evaluated newval, other times 0. But a heap-allocated + // ExprValue is not always passed to coerce_value(), so we + // have to manage it here, where we know it is always a 'new'. + if (retval != newval) + { + delete newval; + newval = 0; + } + + return retval; +} + +// Private operations. + +// @@@ (JP) CORBA 2.6 and earlier say that in a constant expression, +// each subexpression must fall within the range of the assigned type. +// However, this may be hard for the compiler in some cases (must +// evaluate all grouping possibilities). So there is an outstanding +// issue, #1139, and the best guess is that it will ultimately be +// decided that only the final value must fall within the range of +// the assigned type. So there are no checks here, only in coerce(). + +// Apply binary operators to an AST_Expression after evaluating +// its sub-expressions. +// Operations supported: '+', '-', '*', '/' +AST_Expression::AST_ExprValue * +AST_Expression::eval_bin_op (AST_Expression::EvalKind ek) +{ + AST_ExprValue *retval = 0; + + if (this->pd_v1 == 0 || this->pd_v2 == 0) + { + return 0; + } + + this->pd_v1->set_ev (this->pd_v1->eval_internal (ek)); + this->pd_v2->set_ev (this->pd_v2->eval_internal (ek)); + + if (this->pd_v1->ev () == 0 || this->pd_v2->ev () == 0) + { + return 0; + } + + ACE_NEW_RETURN (retval, + AST_ExprValue, + 0); + +#if !defined (ACE_LACKS_LONGLONG_T) + if (ek == EK_ulonglong) + { + this->pd_v1->set_ev (this->pd_v1->coerce (EV_ulonglong)); + this->pd_v2->set_ev (this->pd_v2->coerce (EV_ulonglong)); + retval->et = EV_ulonglong; + + switch (this->pd_ec) + { + case EC_add: + retval->u.ullval = + this->pd_v1->ev ()->u.ullval + this->pd_v2->ev ()->u.ullval; + break; + case EC_minus: + retval->u.ullval = + this->pd_v1->ev ()->u.ullval - this->pd_v2->ev ()->u.ullval; + break; + case EC_mul: + retval->u.ullval = + this->pd_v1->ev ()->u.ullval * this->pd_v2->ev ()->u.ullval; + break; + case EC_div: + if (this->pd_v2->ev ()->u.ullval == 0) + { + return 0; + } + + retval->u.ullval = + this->pd_v1->ev ()->u.ullval / this->pd_v2->ev ()->u.ullval; + break; + default: + return 0; + } + } + else if (ek == EK_longlong) + { + this->pd_v1->set_ev (this->pd_v1->coerce (EV_longlong)); + this->pd_v2->set_ev (this->pd_v2->coerce (EV_longlong)); + retval->et = EV_longlong; + + switch (this->pd_ec) + { + case EC_add: + retval->u.llval = + this->pd_v1->ev ()->u.llval + this->pd_v2->ev ()->u.llval; + break; + case EC_minus: + retval->u.llval = + this->pd_v1->ev ()->u.llval - this->pd_v2->ev ()->u.llval; + break; + case EC_mul: + retval->u.llval = + this->pd_v1->ev ()->u.llval * this->pd_v2->ev ()->u.llval; + break; + case EC_div: + if (this->pd_v2->ev ()->u.llval == 0) + { + return 0; + } + + retval->u.llval = + this->pd_v1->ev ()->u.llval / this->pd_v2->ev ()->u.llval; + break; + default: + return 0; + } + } + else +#endif + { + this->pd_v1->set_ev (this->pd_v1->coerce (EV_double)); + this->pd_v2->set_ev (this->pd_v2->coerce (EV_double)); + retval->et = EV_double; + + switch (this->pd_ec) + { + case EC_add: + retval->u.dval = + this->pd_v1->ev ()->u.dval + this->pd_v2->ev ()->u.dval; + break; + case EC_minus: + retval->u.dval = + this->pd_v1->ev ()->u.dval - this->pd_v2->ev ()->u.dval; + break; + case EC_mul: + retval->u.dval = + this->pd_v1->ev ()->u.dval * this->pd_v2->ev ()->u.dval; + break; + case EC_div: + if (this->pd_v2->ev ()->u.dval == 0.0) + { + return 0; + } + + retval->u.dval = + this->pd_v1->ev ()->u.dval / this->pd_v2->ev ()->u.dval; + break; + default: + return 0; + } + } + + return retval; +} +// Apply binary operators to an AST_Expression after evaluating +// its sub-expressions. +// Operations supported: '%' +AST_Expression::AST_ExprValue * +AST_Expression::eval_mod_op (AST_Expression::EvalKind ek) +{ + AST_ExprValue *retval = 0; + + if (this->pd_v1 == 0 || this->pd_v2 == 0) + { + return 0; + } + + this->pd_v1->set_ev (this->pd_v1->eval_internal (ek)); + this->pd_v2->set_ev (this->pd_v2->eval_internal (ek)); + + if (this->pd_v1->ev () == 0 || this->pd_v2->ev () == 0) + { + return 0; + } + + ACE_NEW_RETURN (retval, + AST_ExprValue, + 0); + +#if !defined (ACE_LACKS_LONGLONG_T) + if (ek == EK_ulonglong) + { + this->pd_v1->set_ev (this->pd_v1->coerce (EV_ulonglong)); + this->pd_v2->set_ev (this->pd_v2->coerce (EV_ulonglong)); + retval->et = EV_ulonglong; + + if (this->pd_v2->ev ()->u.ullval == 0) + { + return 0; + } + + retval->u.ullval = + this->pd_v1->ev ()->u.ullval % this->pd_v2->ev ()->u.ullval; + } + else if (ek == EK_longlong) + { + this->pd_v1->set_ev (this->pd_v1->coerce (EV_longlong)); + this->pd_v2->set_ev (this->pd_v2->coerce (EV_longlong)); + retval->et = EV_longlong; + + if (this->pd_v2->ev ()->u.llval == 0) + { + return 0; + } + + retval->u.llval = + this->pd_v1->ev ()->u.llval % this->pd_v2->ev ()->u.llval; + } + else +#endif + if (ek == EK_ulong) + { + this->pd_v1->set_ev (this->pd_v1->coerce (EV_ulong)); + this->pd_v2->set_ev (this->pd_v2->coerce (EV_ulong)); + retval->et = EV_ulong; + + if (this->pd_v2->ev ()->u.ulval == 0) + { + return 0; + } + + retval->u.ulval = + this->pd_v1->ev ()->u.ulval % this->pd_v2->ev ()->u.ulval; + } + else if (ek == EK_long) + { + this->pd_v1->set_ev (this->pd_v1->coerce (EV_long)); + this->pd_v2->set_ev (this->pd_v2->coerce (EV_long)); + retval->et = EV_long; + + if (this->pd_v2->ev ()->u.lval == 0) + { + return 0; + } + + retval->u.lval = + this->pd_v1->ev ()->u.lval % this->pd_v2->ev ()->u.lval; + } + else + { + return 0; + } + + return retval; +} + +// Apply bitwise operations to an AST_Expression after evaluating +// its sub-expressions. +// Operations supported: '%', '|', '&', '^', '<<', '>>' +AST_Expression::AST_ExprValue * +AST_Expression::eval_bit_op (AST_Expression::EvalKind ek) +{ + AST_Expression::AST_ExprValue *retval = 0; + + if (this->pd_v1 == 0 || this->pd_v2 == 0) + { + return 0; + } + + this->pd_v1->set_ev (this->pd_v1->eval_internal (ek)); + this->pd_v2->set_ev (this->pd_v2->eval_internal (ek)); + + if (this->pd_v1->ev () == 0 || this->pd_v2->ev () == 0 ) + { + return 0; + } + + ACE_NEW_RETURN (retval, + AST_ExprValue, + 0); + +#if !defined (ACE_LACKS_LONGLONG_T) + if (ek == EK_ulonglong) + { + this->pd_v1->set_ev (this->pd_v1->coerce (EV_ulonglong)); + this->pd_v2->set_ev (this->pd_v2->coerce (EV_ulonglong)); + retval->et = EV_ulonglong; + + switch (this->pd_ec) + { + case EC_or: + retval->u.ullval = + this->pd_v1->ev ()->u.ullval | this->pd_v2->ev ()->u.ullval; + break; + case EC_xor: + retval->u.ullval = + this->pd_v1->ev ()->u.ullval ^ this->pd_v2->ev ()->u.ullval; + break; + case EC_and: + retval->u.ullval = + this->pd_v1->ev ()->u.ullval & this->pd_v2->ev ()->u.ullval; + break; + case EC_left: + retval->u.ullval = + this->pd_v1->ev ()->u.ullval << this->pd_v2->ev ()->u.ullval; + break; + case EC_right: + retval->u.ullval = + this->pd_v1->ev ()->u.ullval >> this->pd_v2->ev ()->u.ullval; + break; + default: + return 0; + } + } + else if (ek == EK_longlong) + { + this->pd_v1->set_ev (this->pd_v1->coerce (EV_longlong)); + this->pd_v2->set_ev (this->pd_v2->coerce (EV_longlong)); + retval->et = EV_longlong; + + switch (this->pd_ec) + { + case EC_or: + retval->u.llval = + this->pd_v1->ev ()->u.llval | this->pd_v2->ev ()->u.llval; + break; + case EC_xor: + retval->u.llval = + this->pd_v1->ev ()->u.llval ^ this->pd_v2->ev ()->u.llval; + break; + case EC_and: + retval->u.llval = + this->pd_v1->ev ()->u.llval & this->pd_v2->ev ()->u.llval; + break; + case EC_left: + retval->u.llval = + this->pd_v1->ev ()->u.llval << this->pd_v2->ev ()->u.llval; + break; + case EC_right: + retval->u.llval = + this->pd_v1->ev ()->u.llval >> this->pd_v2->ev ()->u.llval; + break; + default: + return 0; + } + } + else +#endif + if (ek == EK_ulong) + { + this->pd_v1->set_ev (this->pd_v1->coerce (EV_ulong)); + this->pd_v2->set_ev (this->pd_v2->coerce (EV_ulong)); + retval->et = EV_ulong; + + switch (this->pd_ec) + { + case EC_or: + retval->u.ulval = + this->pd_v1->ev ()->u.ulval | this->pd_v2->ev ()->u.ulval; + break; + case EC_xor: + retval->u.ulval = + this->pd_v1->ev ()->u.ulval ^ this->pd_v2->ev ()->u.ulval; + break; + case EC_and: + retval->u.ulval = + this->pd_v1->ev ()->u.ulval & this->pd_v2->ev ()->u.ulval; + break; + case EC_left: + retval->u.ulval = + this->pd_v1->ev ()->u.ulval << this->pd_v2->ev ()->u.ulval; + break; + case EC_right: + retval->u.ulval = + this->pd_v1->ev ()->u.ulval >> this->pd_v2->ev ()->u.ulval; + break; + default: + return 0; + } + } + else if (ek == EK_long) + { + this->pd_v1->set_ev (this->pd_v1->coerce (EV_long)); + this->pd_v2->set_ev (this->pd_v2->coerce (EV_long)); + retval->et = EV_long; + + switch (this->pd_ec) + { + case EC_or: + retval->u.lval = + this->pd_v1->ev ()->u.lval | this->pd_v2->ev ()->u.lval; + break; + case EC_xor: + retval->u.lval = + this->pd_v1->ev ()->u.lval ^ this->pd_v2->ev ()->u.lval; + break; + case EC_and: + retval->u.lval = + this->pd_v1->ev ()->u.lval & this->pd_v2->ev ()->u.lval; + break; + case EC_left: + retval->u.lval = + this->pd_v1->ev ()->u.lval << this->pd_v2->ev ()->u.lval; + break; + case EC_right: + retval->u.lval = + this->pd_v1->ev ()->u.lval >> this->pd_v2->ev ()->u.lval; + break; + default: + return 0; + } + } + else if (ek == EK_bool) + { + this->pd_v1->set_ev (this->pd_v1->coerce (EV_bool)); + this->pd_v2->set_ev (this->pd_v2->coerce (EV_bool)); + retval->et = EV_bool; + + switch (this->pd_ec) + { + case EC_or: + retval->u.bval = + this->pd_v1->ev ()->u.bval | this->pd_v2->ev ()->u.bval; + break; + case EC_xor: + retval->u.bval = + this->pd_v1->ev ()->u.bval ^ this->pd_v2->ev ()->u.bval; + break; + case EC_and: + retval->u.bval = + this->pd_v1->ev ()->u.bval & this->pd_v2->ev ()->u.bval; + break; + case EC_left: + retval->u.bval = + this->pd_v1->ev ()->u.ulval << this->pd_v2->ev ()->u.ulval; + break; + case EC_right: + retval->u.bval = + this->pd_v1->ev ()->u.ulval >> this->pd_v2->ev ()->u.ulval; + break; + default: + return 0; + } + } + else + { + return 0; + } + + return retval; +} + +// Apply unary operators to an AST_Expression after evaluating its +// sub-expression. +// Operations supported: '-', '+', '~' +AST_Expression::AST_ExprValue * +AST_Expression::eval_un_op (AST_Expression::EvalKind ek) +{ + AST_ExprValue *retval = 0; + + if (this->pd_ev != 0) + { + return this->pd_ev; + } + + if (this->pd_v1 == 0) + { + return 0; + } + + this->pd_v1->set_ev (this->pd_v1->eval_internal (ek)); + + if (this->pd_v1->ev () == 0) + { + return 0; + } + + ACE_NEW_RETURN (retval, + AST_ExprValue, + 0); + + retval->et = EV_double; + + switch (this->pd_ec) + { + case EC_u_plus: + this->pd_v1->set_ev (this->pd_v1->coerce (EV_double)); + + if (this->pd_v1->ev () == 0) + { + return 0; + } + + retval->u.dval = this->pd_v1->ev ()->u.dval; + break; + case EC_u_minus: + this->pd_v1->set_ev (this->pd_v1->coerce (EV_double)); + + if (this->pd_v1->ev () == 0) + { + return 0; + } + + retval->u.dval = -(this->pd_v1->ev ()->u.dval); + break; + case EC_bit_neg: + if (this->pd_v1->ev () == 0) + { + return 0; + } + + switch (this->pd_v1->ev ()->et) + { + case EV_short: + retval->et = EV_short; + retval->u.sval = ~this->pd_v1->ev ()->u.sval; + break; + case EV_ushort: + retval->et = EV_ushort; + retval->u.usval = ~this->pd_v1->ev ()->u.usval; + break; + case EV_long: + retval->et = EV_long; + retval->u.lval = ~this->pd_v1->ev ()->u.lval; + break; + case EV_ulong: + retval->et = EV_ulong; + retval->u.ulval = ~this->pd_v1->ev ()->u.ulval; + break; +#if ! defined (ACE_LACKS_LONGLONG_T) + case EV_longlong: + retval->et = EV_longlong; + retval->u.llval = ~this->pd_v1->ev ()->u.llval; + break; + case EV_ulonglong: + retval->et = EV_ulonglong; + retval->u.ullval = ~this->pd_v1->ev ()->u.ullval; + break; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case EV_octet: + retval->et = EV_octet; + retval->u.oval = ~this->pd_v1->ev ()->u.oval; + break; + default: + return 0; + } + + break; + default: + return 0; + } + + return retval; +} + +// Evaluate a symbolic AST_Expression by looking up the named +// symbol. +AST_Expression::AST_ExprValue * +AST_Expression::eval_symbol (AST_Expression::EvalKind ek) +{ + UTL_Scope *s = 0; + AST_Decl *d = 0; + AST_Constant *c = 0; + + // Is there a symbol stored? + if (this->pd_n == 0) + { + idl_global->err ()->eval_error (this); + return 0; + } + + // Get current scope for lookup. + if (idl_global->scopes ().depth () > 0) + { + s = idl_global->scopes ().top_non_null (); + } + + if (s == 0) + { + idl_global->err ()->lookup_error (this->pd_n); + return 0; + } + + // Do lookup. + d = s->lookup_by_name (this->pd_n, + true); + + if (d == 0) + { + idl_global->err ()->lookup_error (this->pd_n); + return 0; + } + + // Is it a constant? + if (d->node_type () != AST_Decl::NT_const + && d->node_type () != AST_Decl::NT_enum_val) + { + idl_global->err ()->constant_expected (this->pd_n, + d); + return 0; + } + + // OK, now evaluate the constant we just got, to produce its value. + c = AST_Constant::narrow_from_decl (d); + + if (c == 0) + { + return 0; + } + + return c->constant_value ()->eval_internal (ek); +} + +bool +AST_Expression::type_mismatch (AST_Expression::ExprType t) +{ + if (this->pd_ev != 0) + { + return incompatible_types (this->pd_ev->et, t); + } + + bool v1_mismatch = 0; + bool v2_mismatch = 0; + + if (this->pd_v1 != 0) + { + v1_mismatch = this->pd_v1->type_mismatch (t); + } + + if (this->pd_v2 != 0) + { + v2_mismatch = this->pd_v2->type_mismatch (t); + } + + return v1_mismatch | v2_mismatch; +} + +// Coerce "this" to the ExprType required. Returns a copy of the +// original ExprValue with the coercion applied, if successful, or +// 0 if failed. +AST_Expression::AST_ExprValue * +AST_Expression::check_and_coerce (AST_Expression::ExprType t, + AST_Decl *d) +{ + if (d != 0) + { + AST_Decl *enum_val = + idl_global->scopes ().top_non_null ()->lookup_by_name (this->pd_n, + 1); + + if (enum_val != 0) + { + AST_Decl *enum_decl = ScopeAsDecl (enum_val->defined_in ()); + + if (d->node_type () == AST_Decl::NT_typedef) + { + AST_Typedef *td = AST_Typedef::narrow_from_decl (d); + d = td->primitive_base_type (); + } + + if (d != enum_decl) + { + idl_global->err ()->incompatible_type_error (this); + return 0; + } + } + } + + if (this->type_mismatch (t)) + { + idl_global->err ()->incompatible_type_error (this); + return 0; + } + + if (d != 0 && d->node_type () == AST_Decl::NT_typedef) + { + this->tdef = d; + } + + return this->coerce (t); +} + +// Coerce "this" to the ExprType required. Returns a copy of the +// original ExprValue with the coercion applied, if successful, or +// 0 if failed. +AST_Expression::AST_ExprValue * +AST_Expression::coerce (AST_Expression::ExprType t) +{ + AST_ExprValue *tmp = 0; + + // First, evaluate it, then try to coerce result type. + // If already evaluated, return the result. + switch (t) + { + case EV_short: + tmp = this->eval_internal (EK_short); + break; + case EV_ushort: + tmp = this->eval_internal (EK_ushort); + break; + case EV_long: + tmp = this->eval_internal (EK_long); + break; + case EV_ulong: + tmp = this->eval_internal (EK_ulong); + break; +#if ! defined (ACE_LACKS_LONGLONG_T) + case EV_longlong: + tmp = this->eval_internal (EK_longlong); + break; + case EV_ulonglong: + tmp = this->eval_internal (EK_ulonglong); + break; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case EV_octet: + tmp = this->eval_internal (EK_octet); + break; + case EV_bool: + tmp = this->eval_internal (EK_bool); + break; + default: + tmp = this->eval_internal (EK_const); + break; + } + + if (tmp == 0) + { + return 0; + } + else + { + delete this->pd_ev; + this->pd_ev = tmp; + } + + // Create a copy to contain coercion result. + AST_ExprValue *copy = 0; + ACE_NEW_RETURN (copy, + AST_ExprValue, + 0); + + copy->et = this->pd_ev->et; + + switch (this->pd_ev->et) + { + case EV_longdouble: + case EV_void: + case EV_none: + delete copy; + return 0; + case EV_enum: + copy->u.ulval = this->pd_ev->u.ulval; + break; + case EV_short: + copy->u.sval = this->pd_ev->u.sval; + break; + case EV_ushort: + copy->u.usval = this->pd_ev->u.usval; + break; + case EV_long: + copy->u.lval = this->pd_ev->u.lval; + break; + case EV_ulong: + copy->u.ulval = this->pd_ev->u.ulval; + break; + case EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) + copy->u.llval = this->pd_ev->u.llval; + break; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + delete copy; + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) + copy->u.ullval = this->pd_ev->u.ullval; + break; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + delete copy; + return 0; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case EV_bool: + copy->u.bval = this->pd_ev->u.bval; + break; + case EV_float: + copy->u.fval = this->pd_ev->u.fval; + break; + case EV_double: + copy->u.dval = this->pd_ev->u.dval; + break; + case EV_char: + copy->u.cval = this->pd_ev->u.cval; + break; + case EV_wchar: + copy->u.wcval = this->pd_ev->u.wcval; + break; + case EV_octet: + copy->u.oval = this->pd_ev->u.oval; + break; + case EV_string: + copy->u.strval = this->pd_ev->u.strval; + break; + case EV_wstring: + copy->u.wstrval = this->pd_ev->u.wstrval; + break; + default: + break; + } + + if (this->pd_ev->et == t) + { + return copy; + } + else + { + return coerce_value (copy, + t); + } +} + +// Eval used internally. +AST_Expression::AST_ExprValue * +AST_Expression::eval_internal (AST_Expression::EvalKind ek) +{ + // Already evaluated? + if (this->pd_ev != 0) + { + return eval_kind (this->pd_ev, + ek); + } + + if (ek == EK_bool || ek == EK_octet) + { + // Operators may be used only with integer or floating point types. + idl_global->err ()->illegal_infix (); + return 0; + } + + // OK, must evaluate operator. + switch (this->pd_ec) + { + case EC_add: + case EC_minus: + case EC_mul: + case EC_div: + this->pd_ev = this->eval_bin_op (ek); + return eval_kind (this->pd_ev, + ek); + case EC_mod: + this->pd_ev = this->eval_mod_op (ek); + return eval_kind (this->pd_ev, + ek); + case EC_or: + case EC_xor: + case EC_and: + case EC_left: + case EC_right: + this->pd_ev = this->eval_bit_op (ek); + return eval_kind (this->pd_ev, + ek); + case EC_u_plus: + case EC_u_minus: + case EC_bit_neg: + this->pd_ev = this->eval_un_op (ek); + return eval_kind (this->pd_ev, + ek); + case EC_symbol: + this->pd_ev = this->eval_symbol (ek); + return eval_kind (this->pd_ev, + ek); + case EC_none: + return 0; + } + + return 0; +} + +// Public operations. + +// Evaluate "this", assigning the value to the pd_ev field. +void +AST_Expression::evaluate (EvalKind ek) +{ + AST_ExprValue *tmp = eval_kind (this->pd_ev, ek); + delete this->pd_ev; + this->pd_ev = tmp; +} + +// Expression equality comparison operator. +bool +AST_Expression::operator== (AST_Expression *vc) +{ + if (this->pd_ec != vc->ec ()) + { + return false; + } + + this->evaluate (EK_const); + vc->evaluate (EK_const); + + if (pd_ev == 0 || vc->ev() == 0) + { + return false; + } + + if (this->pd_ev->et != vc->ev ()->et) + { + return false; + } + + switch (pd_ev->et) + { + case EV_short: + return this->pd_ev->u.sval == vc->ev ()->u.sval ? true : false; + case EV_ushort: + return this->pd_ev->u.usval == vc->ev ()->u.usval ? true : false; + case EV_long: + return this->pd_ev->u.lval == vc->ev ()->u.lval ? true : false; + case EV_ulong: + return this->pd_ev->u.ulval == vc->ev()->u.ulval ? true : false; + case EV_float: + return this->pd_ev->u.fval == vc->ev ()->u.fval ? true : false; + case EV_double: + return this->pd_ev->u.dval == vc->ev ()->u.dval ? true : false; + case EV_char: + return this->pd_ev->u.cval == vc->ev ()->u.cval ? true : false; + case EV_wchar: + return this->pd_ev->u.wcval == vc->ev ()->u.wcval ? true : false; + case EV_octet: + return this->pd_ev->u.oval == vc->ev ()->u.oval ? true : false; + case EV_bool: + return this->pd_ev->u.lval == vc->ev ()->u.lval ? true : false; + case EV_string: + if (this->pd_ev->u.strval == 0) + { + if (vc->ev ()->u.strval == 0) + { + return true; + } + else + { + return false; + } + } + else if (vc->ev ()->u.strval == 0) + { + return false; + } + else + { + return this->pd_ev->u.strval == vc->ev ()->u.strval + ? true + : false; + } + + case EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) + return pd_ev->u.llval == vc->ev ()->u.llval ? true : false; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return false; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) + return pd_ev->u.ullval == vc->ev()->u.ullval ? true : false; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return false; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case EV_longdouble: + case EV_wstring: + case EV_enum: + case EV_void: + case EV_none: + case EV_any: + case EV_object: + return false; + } + + return false; +} + +long +AST_Expression::compare (AST_Expression *vc) +{ + if (this->pd_ec != vc->ec ()) + { + return false; + } + + this->evaluate (EK_const); + vc->evaluate (EK_const); + + if (this->pd_ev == 0 || vc->ev () == 0) + { + return false; + } + + if (this->pd_ev->et != vc->ev ()->et) + { + return false; + } + + switch (this->pd_ev->et) + { + case EV_short: + return this->pd_ev->u.sval == vc->ev ()->u.sval ? true : false; + case EV_ushort: + return this->pd_ev->u.usval == vc->ev ()->u.usval ? true : false; + case EV_long: + return this->pd_ev->u.lval == vc->ev ()->u.lval ? true : false; + case EV_ulong: + return this->pd_ev->u.ulval == vc->ev ()->u.ulval ? true : false; + case EV_float: + return this->pd_ev->u.fval == vc->ev ()->u.fval ? true : false; + case EV_double: + return this->pd_ev->u.dval == vc->ev ()->u.dval ? true : false; + case EV_char: + return this->pd_ev->u.cval == vc->ev ()->u.cval ? true : false; + case EV_wchar: + return this->pd_ev->u.wcval == vc->ev ()->u.wcval ? true : false; + case EV_octet: + return this->pd_ev->u.oval == vc->ev ()->u.oval ? true : false; + case EV_bool: + return this->pd_ev->u.lval == vc->ev ()->u.lval ? true : false; + case EV_string: + if (this->pd_ev->u.strval == 0) + { + if (vc->ev ()->u.strval == 0) + { + return true; + } + else + { + return false; + } + } + else if (vc->ev ()->u.strval == 0) + { + return false; + } + else + { + return this->pd_ev->u.strval == vc->ev ()->u.strval ? true : false; + } + + case EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) + return this->pd_ev->u.llval == vc->ev ()->u.llval ? true : false; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return false; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) + return this->pd_ev->u.ullval == vc->ev ()->u.ullval ? true : false; +#else /* ! defined (ACE_LACKS_LONGLONG_T) */ + return false; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + case EV_longdouble: + case EV_wstring: + case EV_enum: + case EV_void: + case EV_none: + case EV_any: + case EV_object: + return false; + } + + return false; +} + +AST_Decl * +AST_Expression::get_tdef (void) const +{ + return this->tdef; +} + +// Helper functions for expression dumpers. + +// Dump this binary AST_Expression node to the ostream o. +static void +dump_binary_expr (ACE_OSTREAM_TYPE &o, + const char *s, + AST_Expression *n1, + AST_Expression *n2) +{ + if (n1 != 0) + { + n1->dump (o); + } + + o << " " << s << " "; + + if (n2 != 0) + { + n2->dump (o); + } +} + +// Dump this unary AST_Expression node to the ostream o. +static void +dump_unary_expr (ACE_OSTREAM_TYPE &o, + const char *s, + AST_Expression *e) +{ + o << s; + e->dump (o); +} + +// Dump the supplied AST_ExprValue to the ostream o. +static void +dump_expr_val (ACE_OSTREAM_TYPE &o, + AST_Expression::AST_ExprValue *ev) +{ + switch (ev->et) + { + case AST_Expression::EV_short: + o << ev->u.sval; + break; + case AST_Expression::EV_ushort: + o << ev->u.usval; + break; + case AST_Expression::EV_long: + o << ev->u.lval; + break; + case AST_Expression::EV_ulong: + o << ev->u.ulval; + break; + case AST_Expression::EV_float: + o << ev->u.fval; + break; + case AST_Expression::EV_double: + o << ev->u.dval; + break; + case AST_Expression::EV_char: + o << ev->u.cval; + break; + case AST_Expression::EV_wchar: + o << ev->u.wcval; + break; + case AST_Expression::EV_octet: + o << ev->u.oval; + break; + case AST_Expression::EV_bool: + o << (ev->u.bval == true ? "TRUE" : "FALSE"); + break; + case AST_Expression::EV_string: + if (ev->u.strval != 0) + ev->u.strval->dump(o); + case AST_Expression::EV_longlong: +#if ! defined (ACE_LACKS_LONGLONG_T) +// o << ev->u.llval; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + break; + case AST_Expression::EV_ulonglong: +#if ! defined (ACE_LACKS_LONGLONG_T) +// o << ev->u.ullval; +#endif /* ! defined (ACE_LACKS_LONGLONG_T) */ + break; + case AST_Expression::EV_longdouble: + case AST_Expression::EV_wstring: + case AST_Expression::EV_enum: + case AST_Expression::EV_none: + case AST_Expression::EV_void: + case AST_Expression::EV_any: + case AST_Expression::EV_object: + break; + } +} + +// Dump an AST_Expression node to the ostream o. +void +AST_Expression::dump (ACE_OSTREAM_TYPE &o) +{ + // See if it was a constant or was evaluated already. + if (this->pd_ev != 0) + { + dump_expr_val (o, + this->pd_ev); + return; + } + + // OK, must print out an expression. + switch (this->pd_ec) + { + // Binary expressions: + case EC_add: + dump_binary_expr (o, + "+", + this->pd_v1, + this->pd_v2); + break; + case EC_minus: + dump_binary_expr (o, + "-", + this->pd_v1, + this->pd_v2); + break; + case EC_mul: + dump_binary_expr (o, + "*", + this->pd_v1, + this->pd_v2); + break; + case EC_div: + dump_binary_expr (o, + "/", + this->pd_v1, + this->pd_v2); + break; + case EC_mod: + dump_binary_expr (o, + "%", + this->pd_v1, + this->pd_v2); + break; + case EC_or: + dump_binary_expr (o, + "|", + this->pd_v1, + this->pd_v2); + break; + case EC_xor: + dump_binary_expr (o, + "^", + this->pd_v1, + this->pd_v2); + break; + case EC_and: + dump_binary_expr (o, + "&", + this->pd_v1, + this->pd_v2); + break; + case EC_left: + dump_binary_expr (o, + "<<", + this->pd_v1, + this->pd_v2); + break; + case EC_right: + dump_binary_expr (o, + ">>", + this->pd_v1, + this->pd_v2); + break; + // Unary expressions. + case EC_u_plus: + dump_unary_expr (o, + "+", + this->pd_v1); + break; + case EC_u_minus: + dump_unary_expr (o, + "-", + this->pd_v1); + break; + case EC_bit_neg: + dump_unary_expr (o, + "~", + this->pd_v1); + break; + // Unevaluated symbol. + case EC_symbol: + this->pd_n->dump (o); + break; + case EC_none: + break; + default: + o << ACE_TEXT ("unsupported dump mode for expression with ec == ") + << (int) this->pd_ec ; + break; + } +} + +int +AST_Expression::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_expression (this); +} + +void +AST_Expression::destroy (void) +{ + if (0 != this->pd_ev && EV_string == this->pd_ev->et) + { + this->pd_ev->u.strval->destroy (); + delete this->pd_ev->u.strval; + this->pd_ev->u.strval = 0; + } + + delete this->pd_ev; + this->pd_ev = 0; + + if (this->pd_v1 != 0) + { + this->pd_v1->destroy (); + } + + if (this->pd_v2 != 0) + { + this->pd_v2->destroy (); + } + + delete this->pd_v1; + this->pd_v1 = 0; + + delete this->pd_v2; + this->pd_v2 = 0; + + if (this->pd_n != 0) + { + this->pd_n->destroy (); + } + + delete this->pd_n; + this->pd_n = 0; +} + +// Data accessors. + +UTL_Scope * +AST_Expression::defined_in (void) +{ + return this->pd_defined_in; +} + +void +AST_Expression::set_defined_in (UTL_Scope *d) +{ + this->pd_defined_in = d; +} + +long +AST_Expression::line (void) +{ + return this->pd_line; +} + +void +AST_Expression::set_line (long l) +{ + this->pd_line = l; +} + +UTL_String * +AST_Expression::file_name (void) +{ + return this->pd_file_name; +} + +void +AST_Expression::set_file_name (UTL_String *f) +{ + this->pd_file_name = f; +} + +AST_Expression::ExprComb +AST_Expression::ec (void) +{ + return this->pd_ec; +} + +AST_Expression::AST_ExprValue * +AST_Expression::ev (void) +{ + return this->pd_ev; +} + +void +AST_Expression::set_ev (AST_Expression::AST_ExprValue *new_ev) +{ + delete this->pd_ev; + this->pd_ev = new_ev; +} + +AST_Expression * +AST_Expression::v1 (void) +{ + return this->pd_v1; +} + +void +AST_Expression::set_v1 (AST_Expression *e) +{ + this->pd_v1 = e; +} + +AST_Expression * +AST_Expression::v2 (void) +{ + return this->pd_v2; +} + +void +AST_Expression::set_v2 (AST_Expression *e) +{ + this->pd_v2 = e; +} + +UTL_ScopedName * +AST_Expression::n (void) +{ + return this->pd_n; +} + +void +AST_Expression::set_n (UTL_ScopedName *new_n) +{ + this->pd_n = new_n; +} diff --git a/TAO/TAO_IDL/ast/ast_factory.cpp b/TAO/TAO_IDL/ast/ast_factory.cpp new file mode 100644 index 00000000000..9d240c3025e --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_factory.cpp @@ -0,0 +1,351 @@ +// $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. + +*/ + +// AST_Factory nodes denote OBV factory construct declarations +// AST_Factory is a subclass of AST_Decl (it is not a type!) +// and of UTL_Scope (the arguments are managed in a scope). + +#include "ast_factory.h" +#include "ast_argument.h" +#include "ast_exception.h" +#include "ast_visitor.h" +#include "global_extern.h" +#include "utl_err.h" +#include "utl_identifier.h" +#include "utl_exceptlist.h" +#include "utl_namelist.h" + +ACE_RCSID (ast, + ast_factory, + "$Id$") + +AST_Factory::AST_Factory (void) + : COMMON_Base (), + AST_Decl (), + UTL_Scope (), + pd_exceptions (0), + pd_n_exceptions (0), + argument_count_ (-1), + has_native_ (0) +{ +} + +AST_Factory::AST_Factory (UTL_ScopedName *n) + : COMMON_Base (1, + 0), //@@ Always local, never abstract + AST_Decl (AST_Decl::NT_factory, + n), + UTL_Scope (AST_Decl::NT_factory), + pd_exceptions (0), + pd_n_exceptions (0), + argument_count_ (-1), + has_native_ (0) +{ +} + +AST_Factory::~AST_Factory (void) +{ +} + +// Public operations. + +UTL_ExceptList * +AST_Factory::exceptions (void) +{ + return this->pd_exceptions; +} + +int +AST_Factory::n_exceptions (void) +{ + return this->pd_n_exceptions; +} + +// Return the member count. +int +AST_Factory::argument_count (void) +{ + this->compute_argument_attr (); + + return this->argument_count_; +} + +// Return if any argument or the return type is a <native> type. +int +AST_Factory::has_native (void) +{ + this->compute_argument_attr (); + + return this->has_native_; +} + +void +AST_Factory::destroy (void) +{ + if (0 != this->pd_exceptions) + { + this->pd_exceptions->destroy (); + this->pd_exceptions = 0; + } + + this->AST_Decl::destroy (); + this->UTL_Scope::destroy (); +} + +// Private operations. + +// Compute total number of members. +int +AST_Factory::compute_argument_attr (void) +{ + if (this->argument_count_ != -1) + { + return 0; + } + + AST_Decl *d = 0; + AST_Type *type = 0; + AST_Argument *arg = 0; + + this->argument_count_ = 0; + + // If there are elements in this scope. + if (this->nmembers () > 0) + { + for (UTL_ScopeActiveIterator i (this, IK_decls); + !i.is_done (); + i.next ()) + { + // Get the next AST decl node. + d = i.item (); + + if (d->node_type () == AST_Decl::NT_argument) + { + this->argument_count_++; + + arg = AST_Argument::narrow_from_decl (d); + + type = AST_Type::narrow_from_decl (arg->field_type ()); + + if (type->node_type () == AST_Decl::NT_native) + { + this->has_native_ = 1; + } + } + } + } + + return 0; +} + +// Add this AST_Argument node (an factory argument declaration) +// to this scope. +AST_Argument * +AST_Factory::fe_add_argument (AST_Argument *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = lookup_by_name_local (t->local_name(), 0)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +UTL_NameList * +AST_Factory::fe_add_exceptions (UTL_NameList *t) +{ + UTL_ScopedName *nl_n = 0; + AST_Exception *fe = 0; + AST_Decl *d = 0; + + this->pd_exceptions = 0; + + for (UTL_NamelistActiveIterator nl_i (t); !nl_i.is_done (); nl_i.next ()) + { + nl_n = nl_i.item (); + + d = this->lookup_by_name (nl_n, + true); + + if (d == 0 || d->node_type() != AST_Decl::NT_except) + { + idl_global->err ()->lookup_error (nl_n); + return 0; + } + + fe = AST_Exception::narrow_from_decl (d); + + if (fe == 0) + { + idl_global->err ()->error1 (UTL_Error::EIDL_ILLEGAL_RAISES, + this); + return 0; + } + + if (this->pd_exceptions == 0) + { + ACE_NEW_RETURN (this->pd_exceptions, + UTL_ExceptList (fe, + 0), + 0); + } + else + { + UTL_ExceptList *el = 0; + ACE_NEW_RETURN (el, + UTL_ExceptList (fe, + 0), + 0); + + this->pd_exceptions->nconc (el); + } + + this->pd_n_exceptions++; + } + + // This return value is never used, it's easier to + // destroy it here and return 0 than to destroy it + // each place it is passed in. + t->destroy (); + delete t; + t = 0; + return t; +} + +// Dump this AST_Factory node (an OBV factory construct) to the ostream o. +void +AST_Factory::dump (ACE_OSTREAM_TYPE &o) +{ + AST_Decl *d = 0; + + this->dump_i (o, "factory "); + this->local_name ()->dump (o); + this->dump_i (o, "("); + + // Iterator must be explicitly advanced inside the loop. + for (UTL_ScopeActiveIterator i (this, IK_decls); + !i.is_done();) + { + d = i.item (); + d->dump (o); + i.next (); + + if (!i.is_done()) + { + this->dump_i (o, ", "); + } + } + + this->dump_i (o, ")"); + +} + +int +AST_Factory::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_factory (this); +} + +// Data accessors + +// Narrowing. +IMPL_NARROW_METHODS2(AST_Factory, AST_Decl, UTL_Scope) +IMPL_NARROW_FROM_DECL(AST_Factory) +IMPL_NARROW_FROM_SCOPE(AST_Factory) diff --git a/TAO/TAO_IDL/ast/ast_field.cpp b/TAO/TAO_IDL/ast/ast_field.cpp new file mode 100644 index 00000000000..816fc654afc --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_field.cpp @@ -0,0 +1,200 @@ +// $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. + +*/ + +// AST_Fields denote fields in IDL structure, union and exception +// declarations. AST_Field is also used as a superclass of AST_Argument +// and AST_UnionBranch. +// AST_Fields have a field type (a subclass of AST_Type) and a name +// (a UTL_ScopedName). + +// AST_Field supplies two constructors, one to be used in constructing +// AST_Field nodes, the other to be used in constructing AST_Argument +// nodes and AST_UnionBranch nodes. + +#include "ast_field.h" +#include "ast_type.h" +#include "ast_visitor.h" +#include "utl_identifier.h" + +ACE_RCSID (ast, ast_field, "$Id$") + +AST_Field::AST_Field (void) + : COMMON_Base (), + AST_Decl (), + pd_field_type (0), + pd_visibility (vis_NA), + anonymous_type_ (false) +{ +} + +// To be used when constructing an AST_Field node. +AST_Field::AST_Field (AST_Type *ft, + UTL_ScopedName *n, + Visibility vis) + : COMMON_Base (), + AST_Decl (AST_Decl::NT_field, + n), + pd_field_type (ft), + pd_visibility (vis), + anonymous_type_ (false) +{ + AST_Decl::NodeType fnt = ft->node_type (); + + if (AST_Decl::NT_array == fnt || AST_Decl::NT_sequence == fnt) + { + this->anonymous_type_ = true; + } +} + +// To be used when constructing a node of a subclass of AST_Field. +AST_Field::AST_Field (AST_Decl::NodeType nt, + AST_Type *ft, + UTL_ScopedName *n, + Visibility vis) + : COMMON_Base (), + AST_Decl (nt, + n), + pd_field_type (ft), + pd_visibility (vis), + anonymous_type_ (false) +{ + AST_Decl::NodeType fnt = ft->node_type (); + + if (AST_Decl::NT_array == fnt || AST_Decl::NT_sequence == fnt) + { + this->anonymous_type_ = true; + } +} + +AST_Field::~AST_Field (void) +{ +} + +// Dump this AST_Field node to the ostream o. +void +AST_Field::dump (ACE_OSTREAM_TYPE &o) +{ + switch (this->pd_visibility) + { + case vis_PRIVATE: + this->dump_i (o, "private "); + + break; + case vis_PUBLIC: + this->dump_i (o, "public "); + + break; + case vis_NA: + break; + } + + this->pd_field_type->local_name ()->dump (o); + + this->dump_i (o, " "); + + this->local_name ()->dump (o); +} + +int +AST_Field::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_field (this); +} + +void +AST_Field::destroy (void) +{ + if (this->anonymous_type_) + { + this->pd_field_type->destroy (); + delete this->pd_field_type; + this->pd_field_type = 0; + } + + this->AST_Decl::destroy (); +} + +AST_Type * +AST_Field::field_type (void) const +{ + return this->pd_field_type; +} + +AST_Field::Visibility +AST_Field::visibility (void) +{ + return this->pd_visibility; +} + +int +AST_Field::contains_wstring (void) +{ + return this->pd_field_type->contains_wstring (); +} + +// Narrowing methods. +IMPL_NARROW_METHODS1(AST_Field, AST_Decl) +IMPL_NARROW_FROM_DECL(AST_Field) diff --git a/TAO/TAO_IDL/ast/ast_generator.cpp b/TAO/TAO_IDL/ast/ast_generator.cpp new file mode 100644 index 00000000000..bcfe904b83e --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_generator.cpp @@ -0,0 +1,922 @@ +// $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. + +*/ + +// The generator protocol is explained in detail in the IDL CFE +// design document. +// The AST_Generator class provides operations to instantiate any +// of the AST nodes. It contains an operation for every constructor +// of every AST class. + +#include "ast_root.h" +#include "ast_valuebox.h" +#include "ast_valuetype.h" +#include "ast_valuetype_fwd.h" +#include "ast_eventtype.h" +#include "ast_eventtype_fwd.h" +#include "ast_component.h" +#include "ast_component_fwd.h" +#include "ast_home.h" +#include "ast_exception.h" +#include "ast_enum.h" +#include "ast_attribute.h" +#include "ast_union.h" +#include "ast_union_fwd.h" +#include "ast_union_branch.h" +#include "ast_enum_val.h" +#include "ast_array.h" +#include "ast_sequence.h" +#include "ast_string.h" +#include "ast_structure_fwd.h" +#include "ast_native.h" +#include "ast_factory.h" +#include "utl_identifier.h" +#include "nr_extern.h" +#include "ace/OS_NS_wchar.h" + +#include "ast_generator.h" + +ACE_RCSID (ast, + ast_generator, + "$Id$") + +AST_PredefinedType * +AST_Generator::create_predefined_type (AST_PredefinedType::PredefinedType t, + UTL_ScopedName *n) +{ + AST_PredefinedType *retval = 0; + ACE_NEW_RETURN (retval, + AST_PredefinedType (t, + n), + 0); + + return retval; +} + +AST_Module * +AST_Generator::create_module (UTL_Scope *s, + UTL_ScopedName *n) +{ + // We create this first so if we find a module with the + // same name from an included file, we can add its + // members to the new module's scope. + AST_Module *retval = 0; + ACE_NEW_RETURN (retval, + AST_Module (n), + 0); + + AST_Decl *d = 0; + AST_Module *m = 0; + + UTL_ScopeActiveIterator iter (s, + UTL_Scope::IK_decls); + + // Check for another module of the same name in this scope. + while (!iter.is_done ()) + { + d = iter.item (); + + if (d->node_type () == AST_Decl::NT_module) + { + // Does it have the same name as the one we're + // supposed to create. + if (d->local_name ()->compare (n->last_component ())) + { + m = AST_Module::narrow_from_decl (d); + + // Get m's previous_ member, plus all it's decls, + // into the new modules's previous_ member. + retval->add_to_previous (m); + } + } + + iter.next (); + } + + // If this scope is itself a module, and has been previously + // opened, the previous opening may contain a previous opening + // of the module we're creating. + d = ScopeAsDecl (s); + AST_Decl::NodeType nt = d->node_type (); + + if (nt == AST_Decl::NT_module || nt == AST_Decl::NT_root) + { + m = AST_Module::narrow_from_decl (d); + + // AST_Module::previous_ is a set, so it contains each + // entry only once, but previous_ will contain the decls + // from all previous openings. See comment in + // AST_Module::add_to_previous() body. + d = m->look_in_previous (n->last_component ()); + + if (d != 0) + { + if (d->node_type () == AST_Decl::NT_module) + { + m = AST_Module::narrow_from_decl (d); + + retval->add_to_previous (m); + } + } + } + + return retval; +} + +AST_Root * +AST_Generator::create_root (UTL_ScopedName *n) +{ + AST_Root *retval = 0; + ACE_NEW_RETURN (retval, + AST_Root (n), + 0); + + return retval; +} + +AST_Interface * +AST_Generator::create_interface (UTL_ScopedName *n, + AST_Interface **inherits, + long n_inherits, + AST_Interface **inherits_flat, + long n_inherits_flat, + bool is_local, + bool is_abstract) +{ + AST_Interface *retval = 0; + ACE_NEW_RETURN (retval, + AST_Interface (n, + inherits, + n_inherits, + inherits_flat, + n_inherits_flat, + is_local, + is_abstract), + 0); + + return retval; +} + +AST_InterfaceFwd * +AST_Generator::create_interface_fwd (UTL_ScopedName *n, + bool is_local, + bool is_abstract) +{ + AST_Interface *full_defn = this->create_interface (n, + 0, + -1, + 0, + 0, + is_local, + is_abstract); + + AST_InterfaceFwd *retval = 0; + ACE_NEW_RETURN (retval, + AST_InterfaceFwd (full_defn, + n), + 0); + + full_defn->fwd_decl (retval); + return retval; +} + +AST_ValueType * +AST_Generator::create_valuetype (UTL_ScopedName *n, + AST_Interface **inherits, + long n_inherits, + AST_ValueType *inherits_concrete, + AST_Interface **inherits_flat, + long n_inherits_flat, + AST_Interface **supports_list, + long n_supports, + AST_Interface *supports_concrete, + bool is_abstract, + bool is_truncatable, + bool is_custom) +{ + AST_ValueType *retval = 0; + ACE_NEW_RETURN (retval, + AST_ValueType (n, + inherits, + n_inherits, + inherits_concrete, + inherits_flat, + n_inherits_flat, + supports_list, + n_supports, + supports_concrete, + is_abstract, + is_truncatable, + is_custom), + 0); + + // The following helps with OBV_ namespace generation. + AST_Module *m = AST_Module::narrow_from_scope (retval->defined_in ()); + + if (m != 0) + { + m->set_has_nested_valuetype (); + } + + return retval; +} + +AST_ValueTypeFwd * +AST_Generator::create_valuetype_fwd (UTL_ScopedName *n, + bool is_abstract) +{ + AST_ValueType *full_defn = this->create_valuetype (n, + 0, + -1, + 0, + 0, + 0, + 0, + 0, + 0, + is_abstract, + false, + false); + + AST_ValueTypeFwd *retval = 0; + ACE_NEW_RETURN (retval, + AST_ValueTypeFwd (full_defn, + n), + 0); + + full_defn->fwd_decl (retval); + return retval; +} + +AST_EventType * +AST_Generator::create_eventtype (UTL_ScopedName *n, + AST_Interface **inherits, + long n_inherits, + AST_ValueType *inherits_concrete, + AST_Interface **inherits_flat, + long n_inherits_flat, + AST_Interface **supports_list, + long n_supports, + AST_Interface *supports_concrete, + bool is_abstract, + bool is_truncatable, + bool is_custom) +{ + AST_EventType *retval = 0; + ACE_NEW_RETURN (retval, + AST_EventType (n, + inherits, + n_inherits, + inherits_concrete, + inherits_flat, + n_inherits_flat, + supports_list, + n_supports, + supports_concrete, + is_abstract, + is_truncatable, + is_custom), + 0); + + // The following helps with OBV_ namespace generation. + AST_Module *m = AST_Module::narrow_from_scope (retval->defined_in ()); + + if (m != 0) + { + m->set_has_nested_valuetype (); + } + + return retval; +} + +AST_EventTypeFwd * +AST_Generator::create_eventtype_fwd (UTL_ScopedName *n, + bool is_abstract) +{ + AST_EventType *full_defn = this->create_eventtype (n, + 0, + -1, + 0, + 0, + 0, + 0, + 0, + 0, + is_abstract, + false, + false); + + AST_EventTypeFwd *retval = 0; + ACE_NEW_RETURN (retval, + AST_EventTypeFwd (full_defn, + n), + 0); + + full_defn->fwd_decl (retval); + return retval; +} + +AST_Component * +AST_Generator::create_component (UTL_ScopedName *n, + AST_Component *base_component, + AST_Interface **supports_list, + long n_supports, + AST_Interface **supports_flat, + long n_supports_flat) +{ + AST_Component *retval = 0; + ACE_NEW_RETURN (retval, + AST_Component (n, + base_component, + supports_list, + n_supports, + supports_flat, + n_supports_flat), + 0); + + return retval; +} + +AST_ComponentFwd * +AST_Generator::create_component_fwd (UTL_ScopedName *n) +{ + AST_Component *full_defn = this->create_component (n, + 0, + 0, + -1, + 0, + 0); + + AST_ComponentFwd *retval = 0; + ACE_NEW_RETURN (retval, + AST_ComponentFwd (full_defn, + n), + 0); + + full_defn->fwd_decl (retval); + return retval; +} + +AST_Home * +AST_Generator::create_home (UTL_ScopedName *n, + AST_Home *base_home, + AST_Component *managed_component, + AST_ValueType *primary_key, + AST_Interface **supports_list, + long n_supports, + AST_Interface **supports_flat, + long n_supports_flat) +{ + AST_Home *retval = 0; + ACE_NEW_RETURN (retval, + AST_Home (n, + base_home, + managed_component, + primary_key, + supports_list, + n_supports, + supports_flat, + n_supports_flat), + 0); + + return retval; +} + +AST_Exception * +AST_Generator::create_exception (UTL_ScopedName *n, + bool is_local, + bool is_abstract) +{ + AST_Exception *retval = 0; + ACE_NEW_RETURN (retval, + AST_Exception (n, + is_local, + is_abstract), + 0); + + return retval; +} + +AST_Structure * +AST_Generator::create_structure (UTL_ScopedName *n, + bool is_local, + bool is_abstract) +{ + AST_Structure *retval = 0; + ACE_NEW_RETURN (retval, + AST_Structure (n, + is_local, + is_abstract), + 0); + + return retval; +} + +AST_StructureFwd * +AST_Generator::create_structure_fwd (UTL_ScopedName *n) +{ + AST_Structure *full_defn = this->create_structure (n, + false, + false); + AST_StructureFwd *retval = 0; + ACE_NEW_RETURN (retval, + AST_StructureFwd (full_defn, + n), + 0); + + full_defn->fwd_decl (retval); + return retval; +} + +AST_Enum * +AST_Generator::create_enum (UTL_ScopedName *n, + bool is_local, + bool is_abstract) +{ + AST_Enum *retval = 0; + ACE_NEW_RETURN (retval, + AST_Enum (n, + is_local, + is_abstract), + 0); + + return retval; +} + +AST_Operation * +AST_Generator::create_operation (AST_Type *rt, + AST_Operation::Flags fl, + UTL_ScopedName *n, + bool is_local, + bool is_abstract) +{ + AST_Operation *retval = 0; + ACE_NEW_RETURN (retval, + AST_Operation (rt, + fl, + n, + is_local, + is_abstract), + 0); + + return retval; +} + +AST_Field * +AST_Generator::create_field (AST_Type *ft, + UTL_ScopedName *n, + AST_Field::Visibility vis) +{ + AST_Field *retval = 0; + ACE_NEW_RETURN (retval, + AST_Field (ft, + n, + vis), + 0); + + return retval; +} + +AST_Argument * +AST_Generator::create_argument (AST_Argument::Direction d, + AST_Type *ft, + UTL_ScopedName *n) +{ + AST_Argument *retval = 0; + ACE_NEW_RETURN (retval, + AST_Argument (d, + ft, + n), + 0); + + return retval; +} + +AST_Attribute * +AST_Generator::create_attribute (bool ro, + AST_Type *ft, + UTL_ScopedName *n, + bool is_local, + bool is_abstract) +{ + AST_Attribute *retval = 0; + ACE_NEW_RETURN (retval, + AST_Attribute (ro, + ft, + n, + is_local, + is_abstract), + 0); + + return retval; +} + +AST_Union * +AST_Generator::create_union (AST_ConcreteType *dt, + UTL_ScopedName *n, + bool is_local, + bool is_abstract) +{ + AST_Union *retval = 0; + ACE_NEW_RETURN (retval, + AST_Union (dt, + n, + is_local, + is_abstract), + 0); + + return retval; +} + +AST_UnionFwd * +AST_Generator::create_union_fwd (UTL_ScopedName *n) +{ + AST_Union *full_defn = this->create_union (0, + n, + false, + false); + AST_UnionFwd *retval = 0; + ACE_NEW_RETURN (retval, + AST_UnionFwd (full_defn, + n), + 0); + + full_defn->fwd_decl (retval); + return retval; +} + +AST_UnionBranch * +AST_Generator::create_union_branch (UTL_LabelList *ll, + AST_Type *ft, + UTL_ScopedName *n) +{ + AST_UnionBranch *retval = 0; + ACE_NEW_RETURN (retval, + AST_UnionBranch (ll, + ft, + n), + 0); + + return retval; +} + +AST_UnionLabel * +AST_Generator::create_union_label (AST_UnionLabel::UnionLabel ul, + AST_Expression *v) +{ + AST_UnionLabel *retval = 0; + ACE_NEW_RETURN (retval, + AST_UnionLabel (ul, + v), + 0); + + return retval; +} + +AST_Constant * +AST_Generator::create_constant (AST_Expression::ExprType et, + AST_Expression *ev, + UTL_ScopedName *n) +{ + AST_Constant *retval = 0; + ACE_NEW_RETURN (retval, + AST_Constant (et, + ev, + n), + 0); + + return retval; +} + +AST_Expression * +AST_Generator::create_expr (UTL_ScopedName *n) +{ + AST_Expression *retval = 0; + ACE_NEW_RETURN (retval, + AST_Expression (n), + 0); + + return retval; +} + +AST_Expression * +AST_Generator::create_expr (AST_Expression *v, + AST_Expression::ExprType t) +{ + AST_Expression *retval = 0; + ACE_NEW_RETURN (retval, + AST_Expression (v, + t), + 0); + + return retval; +} + +AST_Expression * +AST_Generator::create_expr (AST_Expression::ExprComb c, + AST_Expression *v1, + AST_Expression *v2) +{ + AST_Expression *retval = 0; + ACE_NEW_RETURN (retval, + AST_Expression (c, + v1, + v2), + 0); + + return retval; +} + +AST_Expression * +AST_Generator::create_expr (long v) +{ + AST_Expression *retval = 0; + ACE_NEW_RETURN (retval, + AST_Expression (v), + 0); + + return retval; +} + +AST_Expression * +AST_Generator::create_expr (bool b) +{ + AST_Expression *retval = 0; + ACE_NEW_RETURN (retval, + AST_Expression (b), + 0); + + return retval; +} + +AST_Expression * +AST_Generator::create_expr (idl_uns_long v, + AST_Expression::ExprType t) +{ + AST_Expression *retval = 0; + ACE_NEW_RETURN (retval, + AST_Expression (v, + t), + 0); + + return retval; +} + +AST_Expression * +AST_Generator::create_expr (UTL_String *s) +{ + AST_Expression *retval = 0; + ACE_NEW_RETURN (retval, + AST_Expression (s), + 0); + + return retval; +} + +AST_Expression * +AST_Generator::create_expr (char c) +{ + AST_Expression *retval = 0; + ACE_NEW_RETURN (retval, + AST_Expression (c), + 0); + + return retval; +} + +AST_Expression * +AST_Generator::create_expr (ACE_OutputCDR::from_wchar wc) +{ + AST_Expression *retval = 0; + ACE_NEW_RETURN (retval, + AST_Expression (wc), + 0); + + return retval; +} + +AST_Expression * +AST_Generator::create_expr (char *s) +{ + AST_Expression *retval = 0; + ACE_NEW_RETURN (retval, + AST_Expression (s), + 0); + + return retval; +} + +AST_Expression * +AST_Generator::create_expr (double d) +{ + AST_Expression *retval = 0; + ACE_NEW_RETURN (retval, + AST_Expression (d), + 0); + + return retval; +} + +AST_EnumVal * +AST_Generator::create_enum_val (unsigned long v, + UTL_ScopedName *n) +{ + AST_EnumVal *retval = 0; + ACE_NEW_RETURN (retval, + AST_EnumVal (v, + n), + 0); + + return retval; +} + +AST_Array * +AST_Generator::create_array (UTL_ScopedName *n, + unsigned long ndims, + UTL_ExprList *dims, + bool is_local, + bool is_abstract) +{ + AST_Array *retval = 0; + ACE_NEW_RETURN (retval, + AST_Array (n, + ndims, + dims, + is_local, + is_abstract), + 0); + + return retval; +} + +AST_Sequence * +AST_Generator::create_sequence (AST_Expression *ms, + AST_Type *bt, + UTL_ScopedName *n, + bool is_local, + bool is_abstract) +{ + AST_Sequence *retval = 0; + ACE_NEW_RETURN (retval, + AST_Sequence (ms, + bt, + n, + is_local, + is_abstract), + 0); + + return retval; +} + +AST_String * +AST_Generator::create_string (AST_Expression *ms) +{ + Identifier id ("string"); + UTL_ScopedName n (&id, + 0); + + AST_String *retval = 0; + ACE_NEW_RETURN (retval, + AST_String (AST_Decl::NT_string, + &n, + ms), + 0); + + return retval; +} + +AST_String * +AST_Generator::create_wstring (AST_Expression *ms) +{ + Identifier id (sizeof (ACE_CDR::WChar) == 1 + ? "string" + : "wstring"); + UTL_ScopedName n (&id, + 0); + AST_Decl::NodeType nt = sizeof (ACE_CDR::WChar) == 1 + ? AST_Decl::NT_string + : AST_Decl::NT_wstring; + + AST_String *retval = 0; + ACE_NEW_RETURN (retval, + AST_String (nt, + &n, + ms, + sizeof (ACE_OS::WChar)), + 0); + + return retval; +} + +AST_Typedef * +AST_Generator::create_typedef (AST_Type *bt, + UTL_ScopedName *n, + bool is_local, + bool is_abstract) +{ + AST_Typedef *retval = 0; + ACE_NEW_RETURN (retval, + AST_Typedef (bt, + n, + is_local, + is_abstract), + 0); + + return retval; +} + +AST_Native * +AST_Generator::create_native (UTL_ScopedName *n) +{ + AST_Native *retval = 0; + ACE_NEW_RETURN (retval, + AST_Native (n), + 0); + + return retval; +} + +AST_Factory * +AST_Generator::create_factory (UTL_ScopedName *n) +{ + AST_Factory *retval = 0; + ACE_NEW_RETURN (retval, + AST_Factory (n), + 0); + + return retval; +} + +AST_ValueBox * +AST_Generator::create_valuebox (UTL_ScopedName *n, + AST_Type *boxed_type) +{ + AST_ValueBox *retval = 0; + ACE_NEW_RETURN (retval, + AST_ValueBox (n, boxed_type), + 0); + + return retval; +} diff --git a/TAO/TAO_IDL/ast/ast_home.cpp b/TAO/TAO_IDL/ast/ast_home.cpp new file mode 100644 index 00000000000..fa65bd3e1a0 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_home.cpp @@ -0,0 +1,252 @@ +// $Id$ + +#include "ast_home.h" +#include "ast_component.h" +#include "ast_valuetype.h" +#include "ast_operation.h" +#include "ast_visitor.h" +#include "utl_identifier.h" +#include "utl_indenter.h" +#include "utl_err.h" +#include "global_extern.h" + +ACE_RCSID (ast, + ast_home, + "$Id$") + +AST_Home::AST_Home (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + UTL_Scope (), + AST_Interface (), + pd_base_home (0), + pd_managed_component (0), + pd_primary_key (0) +{ +} + +AST_Home::AST_Home (UTL_ScopedName *n, + AST_Home *base_home, + AST_Component *managed_component, + AST_ValueType *primary_key, + AST_Interface **supports, + long n_supports, + AST_Interface **supports_flat, + long n_supports_flat) + : COMMON_Base (false, + false), + AST_Decl (AST_Decl::NT_home, + n), + AST_Type (AST_Decl::NT_home, + n), + UTL_Scope (AST_Decl::NT_home), + AST_Interface (n, + supports, + n_supports, + supports_flat, + n_supports_flat, + false, + false), + pd_base_home (base_home), + pd_managed_component (managed_component), + pd_primary_key (primary_key) +{ + if (primary_key != 0) + { + idl_global->primary_keys ().enqueue_tail (primary_key); + } +} + +AST_Home::~AST_Home (void) +{ +} + +AST_Decl * +AST_Home::look_in_inherited (UTL_ScopedName *e, + bool treat_as_ref) +{ + AST_Decl *d = 0; + + if (this->pd_base_home != 0) + { + d = this->pd_base_home->lookup_by_name (e, treat_as_ref); + } + + return d; +} + +// Look through supported interface list. +AST_Decl * +AST_Home::look_in_supported (UTL_ScopedName *e, + bool treat_as_ref) +{ + AST_Decl *d = 0; + AST_Interface **is = 0; + long nis = -1; + + // Can't look in an interface which was not yet defined. + if (!this->is_defined ()) + { + idl_global->err ()->fwd_decl_lookup (this, + e); + return 0; + } + + // OK, loop through supported interfaces. + + // (Don't leave the inheritance hierarchy, no module or global ...) + // Find all and report ambiguous results as error. + + for (nis = this->n_supports (), is = this->supports (); + nis > 0; + nis--, is++) + { + d = (*is)->lookup_by_name (e, + treat_as_ref, + 0 /* not in parent */); + if (d != 0) + { + break; + } + } + + return d; +} + +AST_Home * +AST_Home::base_home (void) const +{ + return this->pd_base_home; +} + +// These next two look ugly, but it is to keep from having to +// create separate visitors for homes in the back end. + +AST_Interface ** +AST_Home::supports (void) const +{ + return this->pd_base_home ? this->inherits () + 1 : this->inherits (); +} + +long +AST_Home::n_supports (void) const +{ + return this->n_inherits (); +} + +AST_Component * +AST_Home::managed_component (void) const +{ + return this->pd_managed_component; +} + +AST_ValueType * +AST_Home::primary_key (void) const +{ + return this->pd_primary_key; +} + +ACE_Unbounded_Queue<AST_Operation *> & +AST_Home::factories (void) +{ + return this->pd_factories; +} + +ACE_Unbounded_Queue<AST_Operation *> & +AST_Home::finders (void) +{ + return this->pd_finders; +} + +void +AST_Home::destroy (void) +{ + // We have to go through these conniptions to destroy + // a home because its decls (for which there are no + // copy constructors) are assigned to the scope + // of the equivalent interface, which will destroy + // them. But we still have to destroy the containers + // for those references, which may be private or + // protected. + + delete [] this->inherits (); + delete [] this->inherits_flat (); + + delete [] this->pd_decls; + this->pd_decls = 0; + this->pd_decls_allocated = 0; + this->pd_decls_used = 0; + + delete [] this->pd_referenced; + this->pd_referenced = 0; + this->pd_referenced_allocated = 0; + this->pd_referenced_used = 0; + + // These are stored by copying the Identifier. + for (long i = 0; i < this->pd_name_referenced_used; ++i) + { + this->pd_name_referenced[i]->destroy (); + delete this->pd_name_referenced[i]; + this->pd_name_referenced[i] = 0; + } + + delete [] this->pd_name_referenced; + this->pd_name_referenced = 0; + this->pd_name_referenced_allocated = 0; + this->pd_name_referenced_used = 0; + + // Skip AST_Interface, since the home's decls + // are added to the equivalent interface, and + // they should get destroyed there. + this->AST_Type::destroy (); +} + +void +AST_Home::dump (ACE_OSTREAM_TYPE &o) +{ + this->dump_i (o, "home "); + + this->local_name ()->dump (o); + + this->dump_i (o, " "); + + if (this->pd_base_home != 0) + { + this->dump_i (o, ": "); + this->pd_base_home->local_name ()->dump (o); + } + + if (this->pd_managed_component != 0) + { + this->dump_i (o, "\n"); + this->dump_i (o, "manages "); + this->pd_managed_component->local_name ()->dump (o); + } + + if (this->pd_primary_key != 0) + { + this->dump_i (o, "\n"); + this->dump_i (o, "primary key "); + this->pd_primary_key->local_name ()->dump (o); + } + + this->dump_i (o, " {\n"); + + UTL_Scope::dump (o); + idl_global->indent ()->skip_to (o); + + this->dump_i (o, "}"); +} + +int +AST_Home::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_home (this); +} + + // Narrowing. +IMPL_NARROW_METHODS1(AST_Home, AST_Interface) +IMPL_NARROW_FROM_DECL(AST_Home) +IMPL_NARROW_FROM_SCOPE(AST_Home) + diff --git a/TAO/TAO_IDL/ast/ast_interface.cpp b/TAO/TAO_IDL/ast/ast_interface.cpp new file mode 100644 index 00000000000..64bb76d9e96 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_interface.cpp @@ -0,0 +1,1682 @@ +// $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. + +*/ + +// AST_Interfaces denote IDL interface definitions +// AST_Interfaces are subclasses of AST_Type and UTL_Scope +// AST_Interfaces have an array of inherited interfaces and +// a count of the number of inherited interfaces. This count +// represents the total number of unique (recursively) inherited +// interfaces. + +#include "ast_interface.h" +#include "ast_interface_fwd.h" +#include "ast_valuetype.h" +#include "ast_component.h" +#include "ast_constant.h" +#include "ast_exception.h" +#include "ast_attribute.h" +#include "ast_operation.h" +#include "ast_field.h" +#include "ast_enum.h" +#include "ast_enum_val.h" +#include "ast_union.h" +#include "ast_union_fwd.h" +#include "ast_structure_fwd.h" +#include "ast_native.h" +#include "ast_visitor.h" +#include "ast_extern.h" +#include "utl_err.h" +#include "utl_identifier.h" +#include "utl_indenter.h" +#include "utl_string.h" +#include "global_extern.h" +#include "nr_extern.h" + +#include "ace/streams.h" + +ACE_RCSID (ast, + ast_interface, + "$Id$") + +AST_Interface::AST_Interface (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + UTL_Scope (), + pd_inherits (0), + pd_n_inherits (0), + pd_inherits_flat (0), + pd_n_inherits_flat (0), + home_equiv_ (false), + fwd_decl_ (0) +{ + this->size_type (AST_Type::VARIABLE); // Always the case. + this->has_constructor (true); // Always the case. +} + +AST_Interface::AST_Interface (UTL_ScopedName *n, + AST_Interface **ih, + long nih, + AST_Interface **ih_flat, + long nih_flat, + bool local, + bool abstract) + : COMMON_Base (local, + abstract), + AST_Decl (AST_Decl::NT_interface, + n), + AST_Type (AST_Decl::NT_interface, + n), + UTL_Scope (AST_Decl::NT_interface), + pd_inherits (ih), + pd_n_inherits (nih), + pd_inherits_flat (ih_flat), + pd_n_inherits_flat (nih_flat), + home_equiv_ (false), + fwd_decl_ (0) +{ + this->size_type (AST_Type::VARIABLE); // always the case + this->has_constructor (true); // always the case +} + +AST_Interface::~AST_Interface (void) +{ +} + +void +AST_Interface::be_replace_operation (AST_Decl *old_op, + AST_Decl *new_op) +{ + this->replace_scope (old_op, + new_op); + + this->replace_referenced (old_op, + new_op); +} + +AST_Operation * +AST_Interface::be_add_operation (AST_Operation *op) +{ + return this->fe_add_operation (op); +} + +bool +AST_Interface::is_defined (void) +{ + // Each instance of a forward declared interface no + // longer has a redefined full definition, so we + // have to backtrack to the fwd decl is_defined(), + // which searches for the one that does. If one + // is found, then we are defined for code generation + // purposes. See AST_InterfaceFwd::destroy() to + // see the difference for cleanup purposes. + return (0 == this->fwd_decl_ + ? this->pd_n_inherits >= 0 + : this->fwd_decl_->is_defined ()); +} + +// Add an AST_Constant node (a constant declaration) to this scope. +AST_Constant * +AST_Interface::fe_add_constant (AST_Constant *t) +{ + AST_Decl *d = 0; + + // Can't add to interface which was not yet defined + if (!this->is_defined ()) + { + idl_global->err ()->error2 (UTL_Error::EIDL_DECL_NOT_DEFINED, + this, + t); + return 0; + } + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor(d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add an AST_Exception node (an exception declaration) to this scope. +AST_Exception * +AST_Interface::fe_add_exception (AST_Exception *t) +{ + AST_Decl *d = 0; + + // Can't add to interface which was not yet defined + if (!this->is_defined ()) + { + idl_global->err ()->error2 (UTL_Error::EIDL_DECL_NOT_DEFINED, + this, + t); + return 0; + } + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add an AST_Attribute node (an attribute declaration) to this scope. +AST_Attribute * +AST_Interface::fe_add_attribute (AST_Attribute *t) +{ + AST_Decl *d = 0; + + // Can't add to interface which was not yet defined. + if (!this->is_defined ()) + { + idl_global->err ()->error2 (UTL_Error::EIDL_DECL_NOT_DEFINED, + this, + t); + return 0; + } + /* + * Already defined and cannot be redefined? Or already used? + */ + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor(d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_Field node (a field declaration) to this scope +// (only for valuetypes). +AST_Field * +AST_Interface::fe_add_field (AST_Field *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + AST_Type *ft = t->field_type (); + UTL_ScopedName *mru = ft->last_referenced_as (); + + if (mru != 0) + { + this->add_to_referenced (ft, + false, + mru->first_component ()); + } + + return t; +} + +// Add an AST_Operation node (an operation declaration) to this scope. +AST_Operation * +AST_Interface::fe_add_operation (AST_Operation *t) +{ + AST_Decl *d = 0; + + // Can't add to interface which was not yet defined. + if (!this->is_defined ()) + { + idl_global->err ()->error2 (UTL_Error::EIDL_DECL_NOT_DEFINED, + this, + t); + return 0; + } + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + else if ((d = this->look_in_inherited (t->name (), false)) != 0) + { + if (d->node_type () == AST_Decl::NT_op) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add an AST_Structure (a struct declaration) to this scope. +AST_Structure * +AST_Interface::fe_add_structure (AST_Structure *t) +{ + AST_Decl *predef = 0; + AST_StructureFwd *fwd = 0; + + if ((predef = this->lookup_for_add (t, false)) != 0) + { + // Treat fwd declared interfaces specially + if (predef->node_type () == AST_Decl::NT_struct_fwd) + { + fwd = AST_StructureFwd::narrow_from_decl (predef); + + if (fwd == 0) + { + return 0; + } + + // Forward declared and not defined yet. + if (!fwd->is_defined ()) + { + if (fwd->defined_in () == this) + { + fwd->set_full_definition (t); + } + else + { + idl_global->err ()->error3 (UTL_Error::EIDL_SCOPE_CONFLICT, + fwd, + t, + this); + + return 0; + } + } + // OK, not illegal redef of forward declaration. Now check whether. + // it has been referenced already. + else if (this->referenced (predef, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + } + else if (!can_be_redefined (predef)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + predef); + + return 0; + } + else if (referenced (predef, t->local_name ()) && !t->is_defined ()) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_StructureFwd node (a forward declaration of an IDL +// struct) to this scope. +AST_StructureFwd * +AST_Interface::fe_add_structure_fwd (AST_StructureFwd *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + AST_Decl::NodeType nt = d->node_type (); + + // There used to be another check here ANDed with the one below: + // d->defined_in () == this. But lookup_for_add() calls only + // lookup_by_name_local(), which does not bump up the scope. + if (nt == AST_Decl::NT_struct_fwd) + { + // It's legal to forward declare something more than once, + // but we need only one entry in the scope for lookup. + AST_StructureFwd *fd = AST_StructureFwd::narrow_from_decl (d); + t->destroy (); + delete t; + t = 0; + return fd; + } + else if (nt == AST_Decl::NT_struct) + { + AST_Structure *s = AST_Structure::narrow_from_decl (d); + t->set_full_definition (s); + + if (t->added () == 0) + { + t->set_added (1); + this->add_to_scope (t); + + // Must check later that all struct and union forward declarations + // are defined in the same IDL file. + AST_record_fwd_decl (t); + } + + return t; + } + else + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + } + } + + // Add it to scope + this->add_to_scope (t); + + // Add it to set of locally referenced symbols + this->add_to_referenced (t, + false, + t->local_name ()); + + // Must check later that all struct and union forward declarations + // are defined in the same IDL file. + AST_record_fwd_decl (t); + return t; +} + +// Add an AST_Enum node (an enum declaration) to this scope. +AST_Enum * +AST_Interface::fe_add_enum (AST_Enum *t) +{ + AST_Decl *d = 0; + + // Can't add to interface which was not yet defined. + if (!this->is_defined ()) + { + idl_global->err ()->error2 (UTL_Error::EIDL_DECL_NOT_DEFINED, + this, + t); + return 0; + } + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add an AST_Union (a union declaration) to this scope. +AST_Union * +AST_Interface::fe_add_union (AST_Union *t) +{ + AST_Decl *predef = 0; + AST_UnionFwd *fwd = 0; + + if ((predef = this->lookup_for_add (t, false)) != 0) + { + // Treat fwd declared interfaces specially + if (predef->node_type () == AST_Decl::NT_union_fwd) + { + fwd = AST_UnionFwd::narrow_from_decl (predef); + + if (fwd == 0) + { + return 0; + } + + // Forward declared and not defined yet. + if (!fwd->is_defined ()) + { + if (fwd->defined_in () == this) + { + fwd->set_full_definition (t); + } + else + { + idl_global->err ()->error3 (UTL_Error::EIDL_SCOPE_CONFLICT, + fwd, + t, + this); + + return 0; + } + } + // OK, not illegal redef of forward declaration. Now check whether. + // it has been referenced already. + else if (this->referenced (predef, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + } + else if (!can_be_redefined (predef)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + predef); + + return 0; + } + else if (referenced (predef, t->local_name ()) && !t->is_defined ()) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_UnionFwd node (a forward declaration of an IDL +// union) to this scope. +AST_UnionFwd * +AST_Interface::fe_add_union_fwd (AST_UnionFwd *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + AST_Decl::NodeType nt = d->node_type (); + + // There used to be another check here ANDed with the one below: + // d->defined_in () == this. But lookup_for_add() calls only + // lookup_by_name_local(), which does not bump up the scope. + if (nt == AST_Decl::NT_union_fwd) + { + // It's legal to forward declare something more than once, + // but we need only one entry in the scope for lookup. + AST_UnionFwd *fd = AST_UnionFwd::narrow_from_decl (d); + t->destroy (); + delete t; + t = 0; + return fd; + } + else if (nt == AST_Decl::NT_union) + { + AST_Union *s = AST_Union::narrow_from_decl (d); + t->set_full_definition (s); + + if (t->added () == 0) + { + t->set_added (1); + this->add_to_scope (t); + + // Must check later that all struct and union forward declarations + // are defined in the same IDL file. + AST_record_fwd_decl (t); + } + + return t; + } + else + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + } + } + + // Add it to scope + this->add_to_scope (t); + + // Add it to set of locally referenced symbols + this->add_to_referenced (t, + false, + t->local_name ()); + + // Must check later that all struct and union forward declarations + // are defined in the same IDL file. + AST_record_fwd_decl (t); + return t; +} + +// Add an AST_EnumVal node (an enumerator) to this scope. +// This is done to conform to the C++ scoping rules which declare +// enumerators in the enclosing scope (in addition to declaring them +// in the enum itself). +AST_EnumVal * +AST_Interface::fe_add_enum_val (AST_EnumVal *t) +{ + AST_Decl *d = 0; + + // Can't add to interface which was not yet defined. + if (!this->is_defined ()) + { + idl_global->err ()->error2 (UTL_Error::EIDL_DECL_NOT_DEFINED, + this, + t); + return 0; + } + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add an AST_Typedef (a typedef) to the current scope. +AST_Typedef * +AST_Interface::fe_add_typedef (AST_Typedef *t) +{ + AST_Decl *d = 0; + + // Can't add to interface which was not yet defined. + if (!this->is_defined ()) + { + idl_global->err ()->error2 (UTL_Error::EIDL_DECL_NOT_DEFINED, + this, + t); + return 0; + } + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + AST_Type *bt = t->base_type (); + UTL_ScopedName *mru = bt->last_referenced_as (); + + if (mru != 0) + { + this->add_to_referenced ( + bt, + false, + mru->first_component () + ); + } + + return t; +} + +// Add an AST_Native (a native declaration) to this scope. +AST_Native * +AST_Interface::fe_add_native (AST_Native *t) +{ + AST_Decl *d = 0; + + // Can't add to interface which was not yet defined. + if (!this->is_defined ()) + { + idl_global->err ()->error2 (UTL_Error::EIDL_DECL_NOT_DEFINED, + this, + t); + return 0; + } + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Dump this AST_Interface node to the ostream o. +void +AST_Interface::dump (ACE_OSTREAM_TYPE &o) +{ + if (this->is_abstract ()) + { + this->dump_i (o, "abstract "); + } + else if (this->is_local ()) + { + this->dump_i (o, "local "); + } + + this->dump_i (o, "interface "); + + this->local_name ()->dump (o); + this->dump_i (o, " "); + + if (this->pd_n_inherits > 0) + { + this->dump_i (o, ": "); + + for (long i = 0; i < this->pd_n_inherits; ++i) + { + this->pd_inherits[i]->local_name ()->dump (o); + + if (i < this->pd_n_inherits - 1) + { + this->dump_i (o, ", "); + } + } + } + + this->dump_i (o, " {\n"); + + UTL_Scope::dump (o); + idl_global->indent ()->skip_to (o); + + this->dump_i (o, "}"); +} + +// This serves for interfaces, valuetypes, components and eventtypes. +void +AST_Interface::fwd_redefinition_helper (AST_Interface *&i, + UTL_Scope *s) +{ + if (i == 0) + { + return; + } + + UTL_Scope *scope = i->defined_in (); + const char *prefix_holder = 0; + + // If our prefix is empty, we check to see if an ancestor has one. + while (ACE_OS::strcmp (i->prefix (), "") == 0 && scope != 0) + { + AST_Decl *parent = ScopeAsDecl (scope); + prefix_holder = parent->prefix (); + + // We have reached global scope. + if (prefix_holder == 0) + { + break; + } + + i->prefix (const_cast<char *> (prefix_holder)); + scope = parent->defined_in (); + } + + // Fwd redefinition should be in the same scope, so local + // lookup is all that's needed. + AST_Decl *d = s->lookup_by_name_local (i->local_name (), + 0); + + AST_Interface *fd = 0; + + if (d != 0) + { + scope = d->defined_in (); + + // If the lookup prefix is empty, we check to see if an ancestor has one. + while (ACE_OS::strcmp (d->prefix (), "") == 0 && scope != 0) + { + AST_Decl *parent = ScopeAsDecl (scope); + prefix_holder = parent->prefix (); + + // We have reached global scope. + if (prefix_holder == 0) + { + break; + } + + d->prefix (const_cast<char *> (prefix_holder)); + scope = parent->defined_in (); + } + + // (JP) This could give a bogus error, since typeprefix can + // appear any time after the corresponding declaration. + // The right way to do this is with a separate traversal + // after the entire AST is built. + /* + if (ACE_OS::strcmp (i->prefix (), d->prefix ()) != 0) + { + idl_global->err ()->error1 (UTL_Error::EIDL_PREFIX_CONFLICT, + i); + + return; + } + */ + + fd = AST_Interface::narrow_from_decl (d); + + // Successful? + if (fd == 0) + { + // Should we give an error here? + // No, look in fe_add_interface. + } + // If it is a forward declared interface.. + else if (!fd->is_defined ()) + { + // Check if redefining in same scope. If a module is reopened, + // a new pointer in created, and the first term below will be + // true. In that case, the scoped names must be compared. + if (fd->defined_in () != s + && i->name ()->compare (fd->name ()) != 0) + { + idl_global->err ()->error2 (UTL_Error::EIDL_SCOPE_CONFLICT, + i, + fd); + } + // All OK, do the redefinition. + else + { + AST_Decl::NodeType fd_nt = fd->node_type (); + AST_Decl::NodeType i_nt = i->node_type (); + + // Only redefinition of the same kind. + if (i->is_local () != fd->is_local () + || i_nt != fd_nt + || i->is_abstract () != fd->is_abstract () + ) + { + idl_global->err ()->error2 (UTL_Error::EIDL_REDEF, + i, + fd); + return; + } + + fd->redefine (i); + + // Use full definition node. + i->destroy (); + delete i; + i = fd; + } + } + } +} + +void +AST_Interface::redef_clash_populate_r (AST_Interface *t) +{ + if (this->insert_non_dup (t, 0) == 0) + { + return; + } + + AST_Interface **parents = t->inherits (); + long n_parents = t->n_inherits (); + long i; + + for (i = 0; i < n_parents; ++i) + { + this->redef_clash_populate_r (parents[i]); + } + + AST_Decl::NodeType nt = t->node_type (); + + if (nt == AST_Decl::NT_valuetype) + { + AST_ValueType *v = AST_ValueType::narrow_from_decl (t); + AST_Interface **supports = v->supports (); + long n_supports = v->n_supports (); + + for (i = 0; i < n_supports; ++i) + { + this->redef_clash_populate_r (supports[i]); + } + } + else if (nt == AST_Decl::NT_component) + { + AST_Component *c = AST_Component::narrow_from_decl (t); + AST_Interface **supports = c->supports (); + long n_supports = c->n_supports (); + + for (i = 0; i < n_supports; ++i) + { + this->redef_clash_populate_r (supports[i]); + } + } +} + +bool +AST_Interface::home_equiv (void) const +{ + return this->home_equiv_; +} + +void +AST_Interface::home_equiv (bool val) +{ + this->home_equiv_ = val; +} + +AST_InterfaceFwd * +AST_Interface::fwd_decl (void) const +{ + return this->fwd_decl_; +} + +void +AST_Interface::fwd_decl (AST_InterfaceFwd *node) +{ + this->fwd_decl_ = node; +} + +int +AST_Interface::insert_non_dup (AST_Interface *t, + bool abstract_paths_only) +{ + // Now check if the dequeued element has any ancestors. If yes, insert + // them inside the queue making sure that there are no duplicates. + // If we are doing a component, the inheritance list is actually a + // supports list. + for (long i = 0; i < t->n_inherits (); ++i) + { + // Retrieve the next parent from which the dequeued element inherits. + AST_Interface *parent = t->inherits ()[i]; + + if (abstract_paths_only && ! parent->is_abstract ()) + { + continue; + } + + (void) this->insert_non_dup (parent, abstract_paths_only); + } // end of for loop + + const char *full_name = t->full_name (); + + // Initialize an iterator to search the queue for duplicates. + for (ACE_Unbounded_Queue_Iterator<AST_Interface *> q_iter ( + this->insert_queue + ); + !q_iter.done (); + (void) q_iter.advance ()) + { + // Queue element. + AST_Interface **temp; + + (void) q_iter.next (temp); + + if (!ACE_OS::strcmp (full_name, + (*temp)->full_name ())) + { + // We exist in this queue and cannot be inserted. + return 0; + } + } + + // Initialize an iterator to search the del_queue for duplicates. + for (ACE_Unbounded_Queue_Iterator<AST_Interface *> del_q_iter ( + this->del_queue + ); + !del_q_iter.done (); + (void) del_q_iter.advance ()) + { + // Queue element. + AST_Interface **temp; + + (void) del_q_iter.next (temp); + + if (!ACE_OS::strcmp (full_name, + (*temp)->full_name ())) + { + // We exist in this del_queue and cannot be inserted. + return 0; + } + } + + // Insert the parent in the queue. + if (this->insert_queue.enqueue_tail (t) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_interface::insert_non_dup - " + "enqueue failed\n"), + 0); + } + + return 1; +} + +// This serves only for interfaces. It is overridden for valuetypes, +// components and eventtypes. +void +AST_Interface::redefine (AST_Interface *from) +{ + // 'this' is the full_definition member of a forward + // declared interface. 'from' is the actual full + // definition, which may be in a different scope. + // Since 'this' will replace 'from' upon returning + // from here, we have to update the scope now. + this->pd_n_inherits = from->pd_n_inherits; + unsigned long i = 0; + + unsigned long array_size = + static_cast<unsigned long> (from->pd_n_inherits); + ACE_NEW (this->pd_inherits, + AST_Interface *[array_size]); + + for (i = 0; i < array_size; ++i) + { + this->pd_inherits[i] = from->pd_inherits[i]; + } + + this->pd_n_inherits_flat = from->pd_n_inherits_flat; + array_size = + static_cast<unsigned long> (from->pd_n_inherits_flat); + ACE_NEW (this->pd_inherits_flat, + AST_Interface *[array_size]); + + for (i = 0; i < array_size; ++i) + { + this->pd_inherits_flat[i] = from->pd_inherits_flat[i]; + } + + // We've already checked for inconsistent prefixes. + this->prefix (from->prefix ()); + + this->set_defined_in (from->defined_in ()); + this->set_imported (idl_global->imported ()); + this->set_in_main_file (idl_global->in_main_file ()); + this->set_line (idl_global->lineno ()); + this->set_file_name (idl_global->filename ()->get_string ()); + this->ifr_added_ = from->ifr_added_; + this->ifr_fwd_added_ = from->ifr_fwd_added_; +} + +// Data accessors. + +AST_Interface ** +AST_Interface::inherits (void) const +{ + return this->pd_inherits; +} + +long +AST_Interface::n_inherits (void) const +{ + return this->pd_n_inherits; +} + +AST_Interface ** +AST_Interface::inherits_flat (void) const +{ + return this->pd_inherits_flat; +} + +long +AST_Interface::n_inherits_flat (void) const +{ + return pd_n_inherits_flat; +} + +ACE_Unbounded_Queue<AST_Interface *> & +AST_Interface::get_insert_queue (void) +{ + return this->insert_queue; +} + +ACE_Unbounded_Queue<AST_Interface *> & +AST_Interface::get_del_queue (void) +{ + return this->del_queue; +} + +bool +AST_Interface::redef_clash (void) +{ + this->insert_queue.reset (); + this->redef_clash_populate_r (this); + + AST_Interface **group1_member = 0; + AST_Interface **group2_member = 0; + AST_Decl *group1_member_item = 0; + AST_Decl *group2_member_item = 0; + + int i = 1; + + // Now compare all pairs. + for (ACE_Unbounded_Queue_Iterator<AST_Interface *> group1_iter ( + this->insert_queue + ); + !group1_iter.done (); + (void) group1_iter.advance (), ++i) + { + // Queue element. + (void) group1_iter.next (group1_member); + + for (UTL_ScopeActiveIterator group1_member_items ( + DeclAsScope (*group1_member), + UTL_Scope::IK_decls + ); + !group1_member_items.is_done (); + group1_member_items.next ()) + { + group1_member_item = group1_member_items.item (); + AST_Decl::NodeType nt1 = group1_member_item->node_type (); + + // Only these member types may cause a clash because + // they can't be redefined. + if (nt1 != AST_Decl::NT_op && nt1 != AST_Decl::NT_attr) + { + continue; + } + + Identifier *pid1 = group1_member_item->local_name (); + int j = 0; + + for (ACE_Unbounded_Queue_Iterator<AST_Interface *> group2_iter ( + this->insert_queue + ); + !group2_iter.done (); + (void) group2_iter.advance ()) + { + // Since group1 and group2 are the same list, we can start this + // iterator from where the outer one is. + while (j++ < i) + { + group2_iter.advance (); + } + + if (group2_iter.done ()) + { + break; + } + + // Queue element. + (void) group2_iter.next (group2_member); + + for (UTL_ScopeActiveIterator group2_member_items ( + DeclAsScope (*group2_member), + UTL_Scope::IK_decls + ); + !group2_member_items.is_done (); + group2_member_items.next ()) + { + group2_member_item = group2_member_items.item (); + AST_Decl::NodeType nt2 = group2_member_item->node_type (); + + // Only these member types may cause a clash + // with other parents' member of the same type. + if (nt2 != AST_Decl::NT_op && nt2 != AST_Decl::NT_attr) + { + continue; + } + + Identifier *pid2 = group2_member_item->local_name (); + + if (pid1->compare (pid2) == true) + { + idl_global->err ()->error3 ( + UTL_Error::EIDL_REDEF, + *group1_member, + *group2_member, + group2_member_item + ); + return 1; + } + else if (pid1->case_compare_quiet (pid2) == true) + { + if (idl_global->case_diff_error ()) + { + idl_global->err ()->error3 ( + UTL_Error::EIDL_NAME_CASE_ERROR, + *group1_member, + group1_member_item, + group2_member_item + ); + } + else + { + idl_global->err ()->warning3 ( + UTL_Error::EIDL_NAME_CASE_WARNING, + *group1_member, + group1_member_item, + group2_member_item + ); + } + + return 1; + } + } // end of FOR (group2_member_items) + } // end of FOR (group2_iter) + } // end of FOR (group1_member_items) + } // end of FOR (group1_iter) + + return 0; +} + +// Look through inherited interfaces. +AST_Decl * +AST_Interface::look_in_inherited (UTL_ScopedName *e, + bool treat_as_ref) +{ + AST_Decl *d = 0; + AST_Decl *d_before = 0; + AST_Interface **is = 0; + long nis = -1; + + // Can't look in an interface which was not yet defined. + if (!this->is_defined ()) + { + return 0; + } + + // OK, loop through inherited interfaces. + + // (Don't leave the inheritance hierarchy, no module or global ...) + // Find all and report ambiguous results as error. + + for (nis = this->n_inherits (), is = this->inherits (); + nis > 0; + nis--, is++) + { + d = (*is)->lookup_by_name (e, + treat_as_ref, + 0 /* not in parent */); + if (d != 0) + { + if (d_before == 0) + { + // First result found. + d_before = d; + } + else + { + // Conflict against further results? + if (d != d_before) + { + ACE_ERROR ((LM_ERROR, + "warning in %s line %d: ", + idl_global->filename ()->get_string (), + idl_global->lineno ())); + + e->dump (*ACE_DEFAULT_LOG_STREAM); + + ACE_ERROR ((LM_ERROR, + " is ambiguous in scope.\n" + "Found ")); + + d->name ()->dump (*ACE_DEFAULT_LOG_STREAM); + + ACE_ERROR ((LM_ERROR, + " and ")); + + d_before->name ()->dump (*ACE_DEFAULT_LOG_STREAM); + + ACE_ERROR ((LM_ERROR, + ".\n")); + } + } + } + } + + return d_before; +} + +AST_Decl * +AST_Interface::lookup_for_add (AST_Decl *d, + bool /* treat_as_ref */) +{ + if (d == 0) + { + return 0; + } + + Identifier *id = d->local_name (); + AST_Decl *prev = 0; + AST_Decl::NodeType nt = NT_root; + long nis = -1; + AST_Interface **is = 0; + + if (this->idl_keyword_clash (id) != 0) + { + return 0; + } + + prev = this->lookup_by_name_local (id, + 0); + + if (prev != 0) + { + nt = prev->node_type (); + + if (nt == AST_Decl::NT_op || nt == AST_Decl::NT_attr) + { + return prev; + } + } + + for (nis = this->n_inherits_flat (), is = this->inherits_flat (); + nis > 0; + nis--, is++) + { + prev = (*is)->lookup_by_name_local (id, + 0); + + if (prev != 0) + { + nt = prev->node_type (); + + if (nt == AST_Decl::NT_op || nt == AST_Decl::NT_attr) + { + return prev; + } + } + } + + return 0; +} + +bool +AST_Interface::legal_for_primary_key (void) const +{ + return false; +} + +void +AST_Interface::destroy (void) +{ + delete [] this->pd_inherits; + this->pd_inherits = 0; + this->pd_n_inherits = 0; + + delete [] this->pd_inherits_flat; + this->pd_inherits_flat = 0; + this->pd_n_inherits_flat = 0; + + this->UTL_Scope::destroy (); + this->AST_Type::destroy (); +} + +int +AST_Interface::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_interface (this); +} + +// Narrowing methods. +IMPL_NARROW_METHODS2(AST_Interface, AST_Type, UTL_Scope) +IMPL_NARROW_FROM_DECL(AST_Interface) +IMPL_NARROW_FROM_SCOPE(AST_Interface) diff --git a/TAO/TAO_IDL/ast/ast_interface_fwd.cpp b/TAO/TAO_IDL/ast/ast_interface_fwd.cpp new file mode 100644 index 00000000000..7d9c2e78a1b --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_interface_fwd.cpp @@ -0,0 +1,293 @@ +// $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. + +*/ + +// AST_InterfaceFwd nodes denote forward declarations of IDL interfaces. +// AST_InterfaceFwd nodes have a field containing the full declaration +// of the interface, which is initialized when that declaration is +// encountered. + +#include "ast_interface_fwd.h" +#include "ast_interface.h" +#include "ast_module.h" +#include "ast_visitor.h" +#include "utl_identifier.h" + +ACE_RCSID( ast, + ast_interface_fwd, + "$Id$") + +AST_InterfaceFwd::AST_InterfaceFwd (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + pd_full_definition (0), + is_defined_ (false) +{ +} + +AST_InterfaceFwd::AST_InterfaceFwd (AST_Interface *dummy, + UTL_ScopedName *n) + : COMMON_Base (dummy->is_local (), + dummy->is_abstract ()), + AST_Decl (AST_Decl::NT_interface_fwd, + n), + AST_Type (AST_Decl::NT_interface_fwd, + n), + is_defined_ (false) +{ + // Create a dummy placeholder for the forward declared interface. This + // interface node is not yet defined (n_inherits < 0), so some operations + // will fail. + this->pd_full_definition = dummy; +} + +AST_InterfaceFwd::~AST_InterfaceFwd (void) +{ +} + +// Private operations. + +bool +AST_InterfaceFwd::is_local (void) +{ + return this->full_definition ()->is_local (); +} + +bool AST_InterfaceFwd::is_valuetype (void) +{ + return this->full_definition ()->node_type () == AST_Decl::NT_valuetype; +} + +bool +AST_InterfaceFwd::is_abstract_valuetype (void) +{ + return (this->full_definition ()->is_abstract () + && this->is_valuetype ()); +} + +bool +AST_InterfaceFwd::full_def_seen (void) +{ + UTL_Scope *s = this->defined_in (); + AST_Interface *i = 0; + + // If a full definition is seen in a previous module opening + // or anywhere in the current scope (before or after our + // declaration, reture TRUE. + + if (AST_Decl::NT_module == s->scope_node_type ()) + { + AST_Module *m = AST_Module::narrow_from_scope (s); + AST_Decl *d = m->look_in_previous (this->local_name (), false); + + if (0 != d) + { + i = AST_Interface::narrow_from_decl (d); + + if (0 != i && i->is_defined ()) + { + return true; + } + } + } + + for (UTL_ScopeActiveIterator iter (s, UTL_Scope::IK_decls); + !iter.is_done (); + iter.next ()) + { + i = AST_Interface::narrow_from_decl (iter.item ()); + + if (0 != i && this->local_name ()->compare (i->local_name ())) + { + if (i->is_defined ()) + { + return true; + } + } + } + + return false; +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_InterfaceFwd node to the ostream o. +void +AST_InterfaceFwd::dump (ACE_OSTREAM_TYPE &o) +{ + if (this->is_abstract ()) + { + this->dump_i (o, "abstract "); + } + else if (this->is_local ()) + { + this->dump_i (o, "local "); + } + + this->dump_i (o, "interface "); + + this->local_name ()->dump (o); +} + +int +AST_InterfaceFwd::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_interface_fwd (this); +} + +// Data accessors. + +AST_Interface * +AST_InterfaceFwd::full_definition (void) +{ + return this->pd_full_definition; +} + +void +AST_InterfaceFwd::set_full_definition (AST_Interface *nfd) +{ + delete this->pd_full_definition; + this->pd_full_definition = 0; + this->pd_full_definition = nfd; +} + +bool +AST_InterfaceFwd::is_defined (void) +{ + // Look for the one instance of the fwd decl + // that may have a full definition. + if (!this->is_defined_) + { + AST_Module *m = + AST_Module::narrow_from_scope (this->defined_in ()); + + if (0 != m) + { + AST_Decl *d = m->look_in_previous (this->local_name ()); + + if (0 != d) + { + // We could be looking at a superfluous forward decl + // of an interface already defined. + AST_Interface *full = AST_Interface::narrow_from_decl (d); + + if (0 != full) + { + this->is_defined_ = true; + } + + AST_InterfaceFwd *fwd = + AST_InterfaceFwd::narrow_from_decl (d); + + // Since fwd_redefinition_helper() is called + // before fe_add_interface(), we can't check + // n_inherits() or is_defined(), but added() + // is a sufficient way to tell if our full + // definition has already gone through the + // add_to_scope process. + if (0 != fwd && fwd->full_definition ()->added ()) + { + this->is_defined_ = true; + } + } + } + } + + return this->is_defined_; +} + +void +AST_InterfaceFwd::set_as_defined (void) +{ + this->is_defined_ = true; +} + +void +AST_InterfaceFwd::destroy (void) +{ + // The implementation of is_defined() accomodates + // code generation issues and doesn't have the + // correct semantics here. The older implementation + // of is_defined is used in the IF block below to + // check if our full definition allocation must be + // destroyed. + if (!this->is_defined_) + { + // If our full definition is not defined, it + // means that there was no full definition + // for us in this compilation unit, so we + // have to destroy this allocation. + this->pd_full_definition->destroy (); + delete this->pd_full_definition; + this->pd_full_definition = 0; + } + + this->AST_Type::destroy (); +} + +// Narrowing methods. +IMPL_NARROW_METHODS1 (AST_InterfaceFwd, AST_Type) +IMPL_NARROW_FROM_DECL (AST_InterfaceFwd) diff --git a/TAO/TAO_IDL/ast/ast_module.cpp b/TAO/TAO_IDL/ast/ast_module.cpp new file mode 100644 index 00000000000..4bb08eddfb8 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_module.cpp @@ -0,0 +1,1860 @@ +// $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. + +*/ + +// AST_Modules denote IDL module declarations +// AST_Modules are subclasses of AST_Decl (they are not a type!) and +// of UTL_Scope. + +#include "ast_module.h" +#include "ast_predefined_type.h" +#include "ast_valuebox.h" +#include "ast_valuetype.h" +#include "ast_valuetype_fwd.h" +#include "ast_eventtype.h" +#include "ast_eventtype_fwd.h" +#include "ast_component.h" +#include "ast_component_fwd.h" +#include "ast_home.h" +#include "ast_constant.h" +#include "ast_exception.h" +#include "ast_union.h" +#include "ast_union_fwd.h" +#include "ast_structure_fwd.h" +#include "ast_enum.h" +#include "ast_enum_val.h" +#include "ast_native.h" +#include "ast_generator.h" +#include "ast_visitor.h" +#include "ast_extern.h" +#include "utl_err.h" +#include "utl_identifier.h" +#include "utl_indenter.h" +#include "global_extern.h" +#include "nr_extern.h" + +ACE_RCSID (ast, + ast_module, + "$Id$") + +AST_Module::AST_Module (void) + : AST_Decl (), + UTL_Scope (), + pd_has_nested_valuetype (0) +{ +} + +AST_Module::AST_Module (UTL_ScopedName *n) + : AST_Decl (AST_Decl::NT_module, + n), + UTL_Scope (AST_Decl::NT_module), + pd_has_nested_valuetype (0) +{ +} + +AST_Module::~AST_Module (void) +{ +} + +// Add this AST_PredefinedType node (a predefined type declaration) to +// this scope. + +AST_PredefinedType * +AST_Module::fe_add_predefined_type (AST_PredefinedType *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_Module node (a module declaration) to this scope. +AST_Module * +AST_Module::fe_add_module (AST_Module *t) +{ + AST_Decl *d; + AST_Module *m = 0; + + UTL_Scope *scope = t->defined_in (); + const char *prefix_holder = 0; + + // If our prefix is empty, we check to see if an ancestor has one. + while (ACE_OS::strcmp (t->prefix (), "") == 0 && scope != 0) + { + AST_Decl *parent = ScopeAsDecl (scope); + prefix_holder = parent->prefix (); + + // We have reached global scope. + if (prefix_holder == 0) + { + break; + } + + t->prefix (const_cast<char *> (prefix_holder)); + scope = parent->defined_in (); + } + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + m = AST_Module::narrow_from_decl (d); + + // has_ancestor() returns TRUE if both nodes are the same. + if (t != m) + { + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + const char *prev_prefix = d->prefix (); + const char *this_prefix = t->prefix (); + + if (ACE_OS::strcmp (this_prefix, "") == 0) + { + t->prefix (const_cast<char *> (prev_prefix)); + } + else + { + if (ACE_OS::strcmp (prev_prefix, "") == 0) + { + d->prefix (const_cast<char *> (this_prefix)); + } + // (JP) This could give a bogus error, since typeprefix can + // appear any time after the corresponding declaration. + // The right way to do this is with a separate traversal + // after the entire AST is built. + /* + else + { + if (ACE_OS::strcmp (this_prefix, prev_prefix) != 0) + { + idl_global->err ()->error2 (UTL_Error::EIDL_PREFIX_CONFLICT, + this, + d); + + return 0; + } + } + */ + } + } + + // If this node is not a reopened module, add it to scope and referenced. + if (m == 0 || t != m) + { + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + } + + return t; +} + +// Add this AST_Interface node (an interface declaration) to this scope. +AST_Interface * +AST_Module::fe_add_interface (AST_Interface *t) +{ + if (t->redef_clash ()) + { + return 0; + } + + AST_Decl *predef = 0; + AST_Interface *fwd = 0; + + // Already defined? + if ((predef = this->lookup_for_add (t, false)) != 0) + { + // Treat fwd declared interfaces specially + if (predef->node_type () == AST_Decl::NT_interface) + { + fwd = AST_Interface::narrow_from_decl (predef); + + if (fwd == 0) + { + return 0; + } + + // Forward declared and not defined yet. + if (!fwd->is_defined ()) + { + if (fwd->defined_in () != this) + { + idl_global->err ()->error3 (UTL_Error::EIDL_SCOPE_CONFLICT, + fwd, + t, + this); + + return 0; + } + } + // OK, not illegal redef of forward declaration. Now check whether. + // it has been referenced already. + else if (this->referenced (predef, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + + } + else if (!can_be_redefined (predef)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + predef); + + return 0; + } + else if (referenced (predef, t->local_name ()) && !t->is_defined ()) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + else if (t->has_ancestor (predef)) + { + idl_global->err ()->redefinition_in_scope (t, + predef); + + return 0; + } + } + + // Add it to scope + this->add_to_scope (t); + + // We do this for interfaces, valuetypes and components in + // a different place than we do for structs and unions, + // since fwd declared structs and unions must be defined in + // the same translation unit. + AST_InterfaceFwd *fd = t->fwd_decl (); + + if (0 != fd) + { + fd->set_as_defined (); + } + + // Add it to set of locally referenced symbols + this->add_to_referenced (t, + false, + t->local_name ()); + return t; +} + + +// Add this AST_ValueBox node (a value type declaration) to this scope. +AST_ValueBox * +AST_Module::fe_add_valuebox (AST_ValueBox *t) +{ + AST_Decl *predef = 0; + + // Already defined and cannot be redefined? Or already used? + if ((predef = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (predef)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + predef); + + return 0; + } + else if (referenced (predef, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + else if (t->has_ancestor (predef)) + { + idl_global->err ()->redefinition_in_scope (t, + predef); + + return 0; + } + } + + // Add it to scope + this->add_to_scope (t); + + // Add it to set of locally referenced symbols + this->add_to_referenced (t, + false, + t->local_name ()); + return t; +} + + +// Add this AST_ValueType node (a value type declaration) to this scope. +AST_ValueType * +AST_Module::fe_add_valuetype (AST_ValueType *t) +{ + if (t->redef_clash ()) + { + return 0; + } + + AST_Decl *predef = 0; + AST_ValueType *fwd = 0; + + // Already defined? + if ((predef = this->lookup_for_add (t, false)) != 0) + { + // Treat fwd declared interfaces specially + if (predef->node_type () == AST_Decl::NT_valuetype) + { + fwd = AST_ValueType::narrow_from_decl (predef); + + if (fwd == 0) + { + return 0; + } + + // Forward declared and not defined yet. + if (!fwd->is_defined ()) + { + if (fwd->defined_in () != this) + { + idl_global->err ()->error3 (UTL_Error::EIDL_SCOPE_CONFLICT, + fwd, + t, + this); + + return 0; + } + } + // OK, not illegal redef of forward declaration. Now check whether. + // it has been referenced already. + else if (this->referenced (predef, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + } + else if (!can_be_redefined (predef)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + predef); + + return 0; + } + else if (referenced (predef, t->local_name ()) && !t->is_defined ()) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + else if (t->has_ancestor (predef)) + { + idl_global->err ()->redefinition_in_scope (t, + predef); + + return 0; + } + } + + // Add it to scope + this->add_to_scope (t); + + // We do this for interfaces, valuetypes and components in + // a different place than we do for structs and unions, + // since fwd declared structs and unions must be defined in + // the same translation unit. + AST_InterfaceFwd *fd = t->fwd_decl (); + + if (0 != fd) + { + fd->set_as_defined (); + } + + // Add it to set of locally referenced symbols + this->add_to_referenced (t, + false, + t->local_name ()); + return t; +} + +// Add this AST_EventType node (an event type declaration) to this scope. +AST_EventType * +AST_Module::fe_add_eventtype (AST_EventType *t) +{ + if (t->redef_clash ()) + { + return 0; + } + + AST_Decl *predef = 0; + AST_EventType *fwd = 0; + + // Already defined? + if ((predef = this->lookup_for_add (t, false)) != 0) + { + // Treat fwd declared interfaces specially + if (predef->node_type () == AST_Decl::NT_eventtype) + { + fwd = AST_EventType::narrow_from_decl (predef); + + if (fwd == 0) + { + return 0; + } + + // Forward declared and not defined yet. + if (!fwd->is_defined ()) + { + if (fwd->defined_in () != this) + { + idl_global->err ()->error3 (UTL_Error::EIDL_SCOPE_CONFLICT, + fwd, + t, + this); + + return 0; + } + } + // OK, not illegal redef of forward declaration. Now check whether. + // it has been referenced already. + else if (this->referenced (predef, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + } + else if (!can_be_redefined (predef)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + predef); + + return 0; + } + else if (referenced (predef, t->local_name ()) && !t->is_defined ()) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + else if (t->has_ancestor (predef)) + { + idl_global->err ()->redefinition_in_scope (t, + predef); + + return 0; + } + } + + // Add it to scope + this->add_to_scope (t); + + // Add it to set of locally referenced symbols + this->add_to_referenced (t, + false, + t->local_name ()); + return t; +} + +// Add this AST_Component node (a value type declaration) to this scope. +AST_Component * +AST_Module::fe_add_component (AST_Component *t) +{ + if (t->redef_clash ()) + { + return 0; + } + + AST_Decl *predef = 0; + AST_Component *fwd = 0; + + // Already defined? + if ((predef = this->lookup_for_add (t, false)) != 0) + { + // Treat fwd declared interfaces specially + if (predef->node_type () == AST_Decl::NT_component) + { + fwd = AST_Component::narrow_from_decl (predef); + + if (fwd == 0) + { + return 0; + } + + // Forward declared and not defined yet. + if (!fwd->is_defined ()) + { + if (fwd->defined_in () != this) + { + idl_global->err ()->error3 (UTL_Error::EIDL_SCOPE_CONFLICT, + fwd, + t, + this); + + return 0; + } + } + // OK, not illegal redef of forward declaration. Now check whether. + // it has been referenced already. + else if (this->referenced (predef, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + } + else if (!can_be_redefined (predef)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + predef); + + return 0; + } + else if (referenced (predef, t->local_name ()) && !t->is_defined ()) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + else if (t->has_ancestor (predef)) + { + idl_global->err ()->redefinition_in_scope (t, + predef); + + return 0; + } + } + + // Add it to scope + this->add_to_scope (t); + + // We do this for interfaces, valuetypes and components in + // a different place than we do for structs and unions, + // since fwd declared structs and unions must be defined in + // the same translation unit. + AST_InterfaceFwd *fd = t->fwd_decl (); + + if (0 != fd) + { + fd->set_as_defined (); + } + + // Add it to set of locally referenced symbols + this->add_to_referenced (t, + false, + t->local_name ()); + return t; +} + +// Add this AST_Home node (a value type declaration) to this scope. +AST_Home * +AST_Module::fe_add_home (AST_Home *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // The home's local name is not added to the referenced list, since + // the name will later be mangled to allow a creation of an + // equivalent interface with the original name. + + return t; +} + +// Add this AST_InterfaceFwd node (a forward declaration of an IDL +// interface) to this scope. +AST_InterfaceFwd * +AST_Module::fe_add_interface_fwd (AST_InterfaceFwd *i) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (i, false)) != 0) + { + AST_Decl::NodeType nt = d->node_type (); +/* + if (nt == AST_Decl::NT_interface_fwd) + { + AST_InterfaceFwd *ifwd = AST_InterfaceFwd::narrow_from_decl (d); + i->set_full_definition (ifwd->full_definition ()); + } +*/ + // There used to be another check here ANDed with the one below: + // d->defined_in () == this. But lookup_for_add calls only + // lookup_by_name_local(), which does not bump up the scope, + // and look_in_previous() for modules. If look_in_previous() + // finds something, the scopes will NOT be the same pointer + // value, but the result is what we want. + if (nt == AST_Decl::NT_interface) + { + AST_Interface *itf = AST_Interface::narrow_from_decl (d); + + if (itf == 0) + { + return 0; + } + + if (i->added () == 0) + { + i->set_added (1); + this->add_to_scope (i); + } + + // @@ Redefinition of forward. Type check not implemented. +// i->set_full_definition (itf); // @@ Memory leak. + return i; + } + + if (!can_be_redefined (d)) { + + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + i, + this, + d); + return 0; + } + + // No need to call referenced() for forward declared interafces, + // they can be redeclared after referencing. + + if (i->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (i, + d); + return 0; + } + } + + // Add it to scope + this->add_to_scope (i); + + // Add it to set of locally referenced symbols + this->add_to_referenced (i, + false, + i->local_name ()); + + return i; +} + +// Add this AST_ValueTypeFwd node (a forward declaration of an IDL +// value type) to this scope. +AST_ValueTypeFwd * +AST_Module::fe_add_valuetype_fwd (AST_ValueTypeFwd *v) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (v, false)) != 0) + { + AST_Decl::NodeType nt = d->node_type (); + + if (nt == AST_Decl::NT_valuetype_fwd) + { + AST_ValueTypeFwd *vfwd = AST_ValueTypeFwd::narrow_from_decl (d); + v->set_full_definition (vfwd->full_definition ()); + } + + // There used to be another check here ANDed with the one below: + // d->defined_in () == this. But lookup_for_add calls only + // lookup_by_name_local(), which does not bump up the scope, + // and look_in_previous() for modules. If look_in_previous() + // finds something, the scopes will NOT be the same pointer + // value, but the result is what we want. + if (nt == AST_Decl::NT_valuetype) + { + AST_ValueType *vtf = AST_ValueType::narrow_from_decl (d); + + if (vtf == 0) + { + return 0; + } + + if (v->added () == 0) + { + v->set_added (1); + this->add_to_scope (v); + } + + // @@ Redefinition of forward. Type check not implemented. + v->set_full_definition (vtf); // @@ Memory leak. + return v; + } + + if (!can_be_redefined (d)) { + + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + v, + this, + d); + return 0; + } + + if (this->referenced (d, v->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + v, + this, + d); + return 0; + } + + if (v->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (v, + d); + return 0; + } + } + + // Add it to scope + this->add_to_scope (v); + + // Add it to set of locally referenced symbols + this->add_to_referenced (v, + false, + v->local_name ()); + + return v; +} + +// Add this AST_EventTypeFwd node (a forward declaration of an IDL +// event type) to this scope. +AST_EventTypeFwd * +AST_Module::fe_add_eventtype_fwd (AST_EventTypeFwd *v) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (v, false)) != 0) + { + AST_Decl::NodeType nt = d->node_type (); + + if (nt == AST_Decl::NT_eventtype_fwd) + { + AST_EventTypeFwd *efwd = AST_EventTypeFwd::narrow_from_decl (d); + v->set_full_definition (efwd->full_definition ()); + } + + // There used to be another check here ANDed with the one below: + // d->defined_in () == this. But lookup_for_add calls only + // lookup_by_name_local(), which does not bump up the scope, + // and look_in_previous() for modules. If look_in_previous() + // finds something, the scopes will NOT be the same pointer + // value, but the result is what we want. + if (nt == AST_Decl::NT_eventtype) + { + AST_EventType *vtf = AST_EventType::narrow_from_decl (d); + + if (vtf == 0) + { + return 0; + } + + if (v->added () == 0) + { + v->set_added (1); + this->add_to_scope (v); + } + + // @@ Redefinition of forward. Type check not implemented. + v->set_full_definition (vtf); // @@ Memory leak. + return v; + } + + if (!can_be_redefined (d)) { + + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + v, + this, + d); + return 0; + } + + if (this->referenced (d, v->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + v, + this, + d); + return 0; + } + + if (v->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (v, + d); + return 0; + } + } + + // Add it to scope + this->add_to_scope (v); + + // Add it to set of locally referenced symbols + this->add_to_referenced (v, + false, + v->local_name ()); + + return v; +} + +// Add this AST_ComponentFwd node (a forward declaration of an IDL +// value type) to this scope. +AST_ComponentFwd * +AST_Module::fe_add_component_fwd (AST_ComponentFwd *c) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (c, false)) != 0) + { + AST_Decl::NodeType nt = d->node_type (); + + if (nt == AST_Decl::NT_component_fwd) + { + AST_ComponentFwd *cfwd = AST_ComponentFwd::narrow_from_decl (d); + c->set_full_definition (cfwd->full_definition ()); + } + + // There used to be another check here ANDed with the one below: + // d->defined_in () == this. But lookup_for_add calls only + // lookup_by_name_local(), which does not bump up the scope, + // and look_in_previous() for modules. If look_in_previous() + // finds something, the scopes will NOT be the same pointer + // value, but the result is what we want. + if (nt == AST_Decl::NT_component) + { + AST_Component *cf = AST_Component::narrow_from_decl (d); + + if (cf == 0) + { + return 0; + } + + if (c->added () == 0) + { + c->set_added (1); + this->add_to_scope (c); + } + + // @@ Redefinition of forward. Type check not implemented. + c->set_full_definition (cf); // @@ Memory leak. + return c; + } + + if (!can_be_redefined (d)) { + + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + c, + this, + d); + return 0; + } + + if (this->referenced (d, c->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + c, + this, + d); + return 0; + } + + if (c->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (c, + d); + return 0; + } + } + + // Add it to scope + this->add_to_scope (c); + + // Add it to set of locally referenced symbols + this->add_to_referenced (c, + false, + c->local_name ()); + + return c; +} + +// Add this AST_Constant node (a constant declaration) to this scope. +AST_Constant * +AST_Module::fe_add_constant (AST_Constant *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_Exception node (an exception declaration) to this scope +AST_Exception * +AST_Module::fe_add_exception (AST_Exception *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_Union node (a union declaration) to this scope +AST_Union * +AST_Module::fe_add_union (AST_Union *t) +{ + AST_UnionFwd *fwd = 0; + AST_Decl *predef = this->lookup_for_add (t, false); + + if (predef != 0) + { + // Treat fwd declared interfaces specially + if (predef->node_type () == AST_Decl::NT_union_fwd) + { + fwd = AST_UnionFwd::narrow_from_decl (predef); + + if (fwd == 0) + { + return 0; + } + + // Forward declared and not defined yet. + if (!fwd->is_defined ()) + { + UTL_Scope *s = fwd->defined_in (); + UTL_ScopedName *sn = ScopeAsDecl (s)->name (); + + if (fwd->defined_in () == this + || sn->compare (this->name ()) == 0) + { + fwd->set_full_definition (t); + } + else + { + idl_global->err ()->error3 (UTL_Error::EIDL_SCOPE_CONFLICT, + fwd, + t, + this); + + return 0; + } + } + // OK, not illegal redef of forward declaration. Now check whether. + // it has been referenced already. + else if (this->referenced (predef, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + } + else if (!can_be_redefined (predef)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + predef); + + return 0; + } + else if (referenced (predef, t->local_name ()) && !t->is_defined ()) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_UnionFwd node (a forward declaration of an IDL +// union) to this scope. +AST_UnionFwd * +AST_Module::fe_add_union_fwd (AST_UnionFwd *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + AST_Decl::NodeType nt = d->node_type (); + + if (nt == AST_Decl::NT_union_fwd) + { + AST_UnionFwd *ufwd = AST_UnionFwd::narrow_from_decl (d); + t->set_full_definition (ufwd->full_definition ()); + } + + // There used to be another check here ANDed with the one below: + // d->defined_in () == this. But lookup_for_add calls only + // lookup_by_name_local(), which does not bump up the scope, + // and look_in_previous() for modules. If look_in_previous() + // finds something, the scopes will NOT be the same pointer + // value, but the result is what we want. + if (nt == AST_Decl::NT_union) + { + AST_Union *s = AST_Union::narrow_from_decl (d); + t->set_full_definition (s); + + if (t->added () == 0) + { + t->set_added (1); + this->add_to_scope (t); + + // Must check later that all struct and union forward declarations + // are defined in the same IDL file. + AST_record_fwd_decl (t); + } + + return t; + } + else + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + } + } + + // Add it to scope + this->add_to_scope (t); + + // Add it to set of locally referenced symbols + this->add_to_referenced (t, + false, + t->local_name ()); + + // Must check later that all struct and union forward declarations + // are defined in the same IDL file. + AST_record_fwd_decl (t); + return t; +} + +// Add this AST_Structure node (a struct declaration) to this scope. +AST_Structure * +AST_Module::fe_add_structure (AST_Structure *t) +{ + AST_Decl *predef = 0; + AST_StructureFwd *fwd = 0; + + if ((predef = this->lookup_for_add (t, false)) != 0) + { + // Treat fwd declared interfaces specially + if (predef->node_type () == AST_Decl::NT_struct_fwd) + { + fwd = AST_StructureFwd::narrow_from_decl (predef); + + if (fwd == 0) + { + return 0; + } + + // Forward declared and not defined yet. + if (!fwd->is_defined ()) + { + UTL_Scope *s = fwd->defined_in (); + UTL_ScopedName *sn = ScopeAsDecl (s)->name (); + + if (fwd->defined_in () == this + || sn->compare (this->name ()) == 0) + { + fwd->set_full_definition (t); + } + else + { + idl_global->err ()->error3 (UTL_Error::EIDL_SCOPE_CONFLICT, + fwd, + t, + this); + + return 0; + } + } + // OK, not illegal redef of forward declaration. Now check whether. + // it has been referenced already. + else if (this->referenced (predef, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + } + else if (!can_be_redefined (predef)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + predef); + + return 0; + } + else if (referenced (predef, t->local_name ()) && !t->is_defined ()) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + predef); + + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_StructureFwd node (a forward declaration of an IDL +// struct) to this scope. +AST_StructureFwd * +AST_Module::fe_add_structure_fwd (AST_StructureFwd *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + AST_Decl::NodeType nt = d->node_type (); + + if (nt == AST_Decl::NT_struct_fwd) + { + AST_StructureFwd *sfwd = AST_StructureFwd::narrow_from_decl (d); + t->set_full_definition (sfwd->full_definition ()); + } + + // There used to be another check here ANDed with the one below: + // d->defined_in () == this. But lookup_for_add calls only + // lookup_by_name_local(), which does not bump up the scope, + // and look_in_previous() for modules. If look_in_previous() + // finds something, the scopes will NOT be the same pointer + // value, but the result is what we want. + if (nt == AST_Decl::NT_struct) + { + AST_Structure *s = AST_Structure::narrow_from_decl (d); + t->set_full_definition (s); + + if (t->added () == 0) + { + t->set_added (1); + this->add_to_scope (t); + + // Must check later that all struct and union forward declarations + // are defined in the same IDL file. + AST_record_fwd_decl (t); + } + + return t; + } + else + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + } + } + + // Add it to scope + this->add_to_scope (t); + + // Add it to set of locally referenced symbols + this->add_to_referenced (t, + false, + t->local_name ()); + + // Must check later that all struct and union forward declarations + // are defined in the same IDL file. + AST_record_fwd_decl (t); + return t; +} + +// Add this AST_Enum node (an enum declaration) to this scope. +AST_Enum * +AST_Module::fe_add_enum (AST_Enum *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor(d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_EnumVal node (an enumerator declaration) to this scope +// This is done to conform to the C++ scoping rules which declare +// enumerators in the enclosing scope (in addition to declaring them +// in the enum itself). +AST_EnumVal * +AST_Module::fe_add_enum_val (AST_EnumVal *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add(t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_Typedef node (a typedef) to this scope. +AST_Typedef * +AST_Module::fe_add_typedef (AST_Typedef *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add(t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + AST_Type *bt = t->base_type (); + UTL_ScopedName *mru = bt->last_referenced_as (); + + if (mru != 0) + { + this->add_to_referenced (bt, + false, + mru->first_component ()); + } + + return t; +} + +// Add an AST_Native (a native declaration) to this scope. +AST_Native * +AST_Module::fe_add_native (AST_Native *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Dump this AST_Module node to the ostream o. +void +AST_Module::dump (ACE_OSTREAM_TYPE &o) +{ + this->dump_i (o, "module "); + this->local_name ()->dump (o); + this->dump_i (o, " {\n"); + UTL_Scope::dump (o); + idl_global->indent ()->skip_to (o); + this->dump_i (o, "}"); +} + + +// Involved in OBV_ namespace generation. +void +AST_Module::set_has_nested_valuetype (void) +{ + UTL_Scope *parent = this->defined_in (); + + if (!this->pd_has_nested_valuetype && parent) + { + AST_Module *pm = AST_Module::narrow_from_scope (parent); + + if (pm != 0) + { + pm->set_has_nested_valuetype (); + } + } + + this->pd_has_nested_valuetype = 1; +} + +bool +AST_Module::has_nested_valuetype (void) +{ + return this->pd_has_nested_valuetype; +} + +int +AST_Module::be_add_interface (AST_Interface *i, + AST_Interface *ix) +{ + // Add it to scope. + this->add_to_scope (i, + ix); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (i, + false, + i->local_name (), + ix); + + return 0; +} + +// Has this node been referenced here before? +bool +AST_Module::referenced (AST_Decl *e, + Identifier *id) +{ + bool refd = this->UTL_Scope::referenced (e, id); + + if (refd) + { + return true; + } + + AST_Decl *d = this->look_in_previous (e->local_name (), true); + + if (0 == d) + { + return false; + } + + AST_Type *t = AST_Type::narrow_from_decl (d); + return 0 == t || t->is_defined (); +} + +void +AST_Module::add_to_previous (AST_Module *m) +{ + // Here, we depend on the scope iterator in + // be_generator::create_module (which calls this function) + // to return items in the order they were declared or included. + // That means that the last module returned that matches the name + // of this one will have all the decls from all previous + // reopenings in its previous_ member. + this->previous_ = m->previous_; + + AST_Decl *d = 0; + + for (UTL_ScopeActiveIterator iter (DeclAsScope (m), IK_decls); + !iter.is_done (); + iter.next ()) + { + d = iter.item (); + + // Add all the previous opening's decls (except + // for the predefined types) to the 'previous' list + // of this one. + if (d->node_type () == AST_Decl::NT_pre_defined) + { + AST_PredefinedType *pdt = AST_PredefinedType::narrow_from_decl (d); + + if (pdt->pt () != AST_PredefinedType::PT_pseudo) + { + continue; + } + } + else if (d->node_type () == AST_Decl::NT_interface_fwd) + { + AST_InterfaceFwd *f = AST_InterfaceFwd::narrow_from_decl (d); + AST_Interface *i = f->full_definition (); + + // If i is defined, it means that the interface was forward + // declared AFTER it was defined, perhaps in a subsequent + // opening of the same module - legal, but superfluous. + // Adding d to previous_ in that case can only bung up the + // results of look_in_previous() later, so we skip it. + if (i->is_defined ()) + { + continue; + } + } + + this->previous_.insert (d); + } +} + +AST_Decl * +AST_Module::look_in_previous (Identifier *e, bool ignore_fwd) +{ + AST_Decl **d = 0; + AST_Decl *retval = 0; + + // If there are more than two openings of this module, we want + // to get the last one - the one that will have the decls from + // all the previous openings added to previous_. + for (ACE_Unbounded_Set_Iterator<AST_Decl *> iter (this->previous_); + !iter.done (); + iter.advance ()) + { + iter.next (d); + + if (ignore_fwd) + { + AST_Decl::NodeType nt = (*d)->node_type (); + + if (nt == AST_Decl::NT_interface_fwd + || nt == AST_Decl::NT_eventtype_fwd + || nt == AST_Decl::NT_component_fwd + || nt == AST_Decl::NT_struct_fwd + || nt == AST_Decl::NT_union_fwd + || nt == AST_Decl::NT_valuetype_fwd) + { + continue; + } + } + + if (e->case_compare ((*d)->local_name ())) + { + retval = *d; + } + } + + return retval; +} + +ACE_Unbounded_Set<AST_Decl *> & +AST_Module::previous (void) +{ + return this->previous_; +} + +void +AST_Module::destroy (void) +{ + this->UTL_Scope::destroy (); + this->AST_Decl::destroy (); +} + +int +AST_Module::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_module (this); +} + +// Narrowing methods +IMPL_NARROW_METHODS2(AST_Module, AST_Decl, UTL_Scope) +IMPL_NARROW_FROM_DECL(AST_Module) +IMPL_NARROW_FROM_SCOPE(AST_Module) diff --git a/TAO/TAO_IDL/ast/ast_native.cpp b/TAO/TAO_IDL/ast/ast_native.cpp new file mode 100644 index 00000000000..c8f5b6625c1 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_native.cpp @@ -0,0 +1,65 @@ +// $Id$ + +#include "ast_native.h" +#include "ast_visitor.h" + +ACE_RCSID (ast, + ast_native, + "$Id$") + +AST_Native::AST_Native (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + AST_ConcreteType (), + UTL_Scope (), + AST_Structure (), + AST_Exception () +{ +} + +AST_Native::AST_Native (UTL_ScopedName *n) + : COMMON_Base (), + AST_Decl (AST_Decl::NT_native, + n), + AST_Type (AST_Decl::NT_native, + n), + AST_ConcreteType (AST_Decl::NT_native, + n), + UTL_Scope (AST_Decl::NT_native), + AST_Structure (AST_Decl::NT_native, + n, + true, + false), + AST_Exception (n, + true, + false) +{ +} + +AST_Native::~AST_Native (void) +{ +} + +void +AST_Native::destroy (void) +{ + this->AST_Exception::destroy (); +} + +// Dump this AST_Native node to the ostream o. +void +AST_Native::dump (ACE_OSTREAM_TYPE &o) +{ + AST_Decl::dump (o); +} + +int +AST_Native::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_native (this); +} + +// Narrowing. +IMPL_NARROW_METHODS1(AST_Native, AST_Exception) +IMPL_NARROW_FROM_DECL(AST_Native) diff --git a/TAO/TAO_IDL/ast/ast_operation.cpp b/TAO/TAO_IDL/ast/ast_operation.cpp new file mode 100644 index 00000000000..4efe7f6a6a6 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_operation.cpp @@ -0,0 +1,595 @@ +// $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. + +*/ + +// AST_Operation nodes denote IDL operation declarations +// AST_Operations are a subclass of AST_Decl (they are not a type!) +// and of UTL_Scope (the arguments are managed in a scope). +// AST_Operations have a return type (a subclass of AST_Type), +// a bitfield for denoting various properties of the operation (the +// values are ORed together from constants defined in the enum +// AST_Operation::FLags), a name (a UTL_ScopedName), a context +// (implemented as a list of Strings, a UTL_StrList), and a raises +// clause (implemented as an array of AST_Exceptions). + +#include "ast_operation.h" +#include "ast_predefined_type.h" +#include "ast_argument.h" +#include "ast_exception.h" +#include "ast_visitor.h" +#include "utl_err.h" +#include "utl_namelist.h" +#include "utl_exceptlist.h" +#include "utl_identifier.h" +#include "utl_string.h" +#include "utl_strlist.h" +#include "global_extern.h" + +ACE_RCSID (ast, + ast_operation, + "$Id$") + +AST_Operation::AST_Operation (void) + : COMMON_Base (), + AST_Decl(), + UTL_Scope(), + pd_return_type (0), + pd_flags (OP_noflags), + pd_context (0), + pd_exceptions (0), + argument_count_ (-1), + has_native_ (0) +{ +} + +AST_Operation::AST_Operation (AST_Type *rt, + Flags fl, + UTL_ScopedName *n, + bool local, + bool abstract) + : COMMON_Base (local, + abstract), + AST_Decl(AST_Decl::NT_op, + n), + UTL_Scope(AST_Decl::NT_op), + pd_return_type (rt), + pd_flags (fl), + pd_context (0), + pd_exceptions (0), + argument_count_ (-1), + has_native_ (0) +{ + AST_PredefinedType *pdt = 0; + + // Check that if the operation is oneway, the return type must be void. + if (rt != 0 && pd_flags == OP_oneway) + { + if (rt->node_type () != AST_Decl::NT_pre_defined) + { + idl_global->err ()->error1 (UTL_Error::EIDL_NONVOID_ONEWAY, + this); + } + else + { + pdt = AST_PredefinedType::narrow_from_decl (rt); + + if (pdt == 0 || pdt->pt () != AST_PredefinedType::PT_void) + { + idl_global->err ()->error1 (UTL_Error::EIDL_NONVOID_ONEWAY, + this); + } + } + } +} + +AST_Operation::~AST_Operation (void) +{ +} + +// Public operations. + +int +AST_Operation::void_return_type (void) +{ + AST_Type* type = this->return_type (); + + if (type->node_type () == AST_Decl::NT_pre_defined + && (AST_PredefinedType::narrow_from_decl (type)->pt () + == AST_PredefinedType::PT_void)) + { + return 1; + } + else + { + return 0; + } +} + +// Return the member count. +int +AST_Operation::argument_count (void) +{ + this->compute_argument_attr (); + + return this->argument_count_; +} + +int +AST_Operation::count_arguments_with_direction (int direction_mask) +{ + int count = 0; + + for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + AST_Argument *arg = + AST_Argument::narrow_from_decl (si.item ()); + + if ((arg->direction () & direction_mask) != 0) + { + ++count; + } + } + + return count; +} + + +// Return if any argument or the return type is a <native> type. +int +AST_Operation::has_native (void) +{ + this->compute_argument_attr (); + + return this->has_native_; +} + +void +AST_Operation::destroy (void) +{ + // No need to delete our exception list, the + // destroy() method does it. The UTL_ExceptList + // destroy() method does NOT delete the contained + // exception nodes. + + if (this->pd_exceptions != 0) + { + this->pd_exceptions->destroy (); + this->pd_exceptions = 0; + } + + this->UTL_Scope::destroy (); + this->AST_Decl::destroy (); +} + +// Private operations. + +// Compute total number of members. +int +AST_Operation::compute_argument_attr (void) +{ + if (this->argument_count_ != -1) + { + return 0; + } + + AST_Decl *d = 0; + AST_Type *type = 0; + AST_Argument *arg = 0; + + this->argument_count_ = 0; + + // If there are elements in this scope. + if (this->nmembers () > 0) + { + // Instantiate a scope iterator. + for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + // Get the next AST decl node. + d = si.item (); + + if (d->node_type () == AST_Decl::NT_argument) + { + this->argument_count_++; + + arg = AST_Argument::narrow_from_decl (d); + + type = AST_Type::narrow_from_decl (arg->field_type ()); + + if (type->node_type () == AST_Decl::NT_native) + { + this->has_native_ = 1; + } + } + } + } + + type = AST_Type::narrow_from_decl (this->return_type ()); + + if (type->node_type () == AST_Decl::NT_native) + { + this->has_native_ = 1; + } + + return 0; +} + +// Add this context (a UTL_StrList) to this scope. +UTL_StrList * +AST_Operation::fe_add_context (UTL_StrList *t) +{ + this->pd_context = t; + + return t; +} + +UTL_ExceptList * +AST_Operation::be_add_exceptions (UTL_ExceptList *t) +{ + if (this->pd_exceptions != 0) + { + idl_global->err ()->error1 (UTL_Error::EIDL_ILLEGAL_RAISES, + this); + } + else + { + this->pd_exceptions = t; + } + + return this->pd_exceptions; +} + +AST_Argument * +AST_Operation::be_add_argument (AST_Argument *arg) +{ + this->add_to_scope (arg); + this->add_to_referenced (arg, + 0, + 0); + return arg; +} + +int +AST_Operation::be_insert_exception (AST_Exception *ex) +{ + UTL_ExceptList *new_list = 0; + ACE_NEW_RETURN (new_list, + UTL_ExceptList (ex, + this->pd_exceptions), + -1); + this->pd_exceptions = new_list; + return 0; +} + +// Add these exceptions (identified by name) to this scope. +// This looks up each name to resolve it to the name of a known +// exception, and then adds the referenced exception to the list +// exceptions that this operation can raise. + +// NOTE: No attempt is made to ensure that exceptions are mentioned +// only once.. +UTL_NameList * +AST_Operation::fe_add_exceptions (UTL_NameList *t) +{ + if (0 == t) + { + return 0; + } + + UTL_ScopedName *nl_n = 0; + AST_Exception *fe = 0; + AST_Decl *d = 0; + + this->pd_exceptions = 0; + + for (UTL_NamelistActiveIterator nl_i (t); !nl_i.is_done (); nl_i.next ()) + { + nl_n = nl_i.item (); + d = this->lookup_by_name (nl_n, true); + + if (d == 0) + { + idl_global->err ()->lookup_error (nl_n); + return 0; + } + + bool oneway_op = (this->flags () == AST_Operation::OP_oneway); + fe = AST_Exception::narrow_from_decl (d); + + if (oneway_op && fe != 0) + { + idl_global->err ()->error1 (UTL_Error::EIDL_ILLEGAL_RAISES, + this); + } + + if (fe == 0) + { + idl_global->err ()->error1 (UTL_Error::EIDL_ILLEGAL_RAISES, + this); + return 0; + } + + if (this->pd_exceptions == 0) + { + ACE_NEW_RETURN (this->pd_exceptions, + UTL_ExceptList (fe, + 0), + 0); + } + else + { + UTL_ExceptList *el = 0; + ACE_NEW_RETURN (el, + UTL_ExceptList (fe, + 0), + 0); + + this->pd_exceptions->nconc (el); + } + } + + // This return value is never used, it's easier to + // destroy it here and return 0 than to destroy it + // each place it is passed in. + t->destroy (); + delete t; + t = 0; + return 0; +} + +// Add this AST_Argument node (an operation argument declaration) +// to this scope. +AST_Argument * +AST_Operation::fe_add_argument (AST_Argument *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = lookup_by_name_local (t->local_name(), 0)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Cannot add OUT or INOUT argument to oneway operation. + if ((t->direction () == AST_Argument::dir_OUT + || t->direction() == AST_Argument::dir_INOUT) + && pd_flags == OP_oneway) + { + idl_global->err ()->error2 (UTL_Error::EIDL_ONEWAY_CONFLICT, + t, + this); + return 0; + } + + AST_Type *arg_type = t->field_type (); + + // This error is not caught in y.tab.cpp so we check for it here. + if (arg_type->node_type () == AST_Decl::NT_array + && arg_type->anonymous () == true) + { + idl_global->err ()->syntax_error (idl_global->parse_state ()); + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + UTL_ScopedName *mru = arg_type->last_referenced_as (); + + if (mru != 0) + { + this->add_to_referenced (arg_type, + false, + mru->first_component ()); + } + + return t; +} + +// Dump this AST_Operation node (an operation) to the ostream o. +void +AST_Operation::dump (ACE_OSTREAM_TYPE &o) +{ + AST_Decl *d = 0; + AST_Exception *e = 0; + UTL_String *s = 0; + + if (this->pd_flags == OP_oneway) + { + this->dump_i (o, "oneway "); + } + else if (this->pd_flags == OP_idempotent) + { + this->dump_i (o, "idempotent "); + } + + this->pd_return_type->name ()->dump (o); + this->dump_i (o, " "); + this->local_name ()->dump (o); + this->dump_i (o, "("); + + // Must advance the iterator explicity inside the loop. + for (UTL_ScopeActiveIterator i (this, IK_decls); !i.is_done ();) + { + d = i.item (); + d->dump (o); + i.next (); + + if (!i.is_done()) + { + this->dump_i (o, ", "); + } + } + + this->dump_i (o, ")"); + + if (this->pd_exceptions != 0) + { + this->dump_i (o, " raises("); + + // Must advance the iterator explicity inside the loop. + for (UTL_ExceptlistActiveIterator ei (this->pd_exceptions); + !ei.is_done ();) + { + e = ei.item (); + ei.next (); + e->local_name ()->dump (o); + + if (!ei.is_done()) + { + this->dump_i (o, ", "); + } + } + + this->dump_i (o, ")"); + } + + if (this->pd_context != 0) + { + this->dump_i (o, " context("); + + // Must advance the iterator explicity inside the loop. + for (UTL_StrlistActiveIterator si (this->pd_context); !si.is_done();) + { + s = si.item (); + si.next (); + this->dump_i (o, s->get_string ()); + + if (!si.is_done()) + { + this->dump_i (o, ", "); + } + } + + this->dump_i (o, ")"); + } +} + +int +AST_Operation::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_operation (this); +} + +// Data accessors + +AST_Type * +AST_Operation::return_type (void) +{ + return this->pd_return_type; +} + +AST_Operation::Flags +AST_Operation::flags (void) +{ + return this->pd_flags; +} + +UTL_StrList * +AST_Operation::context (void) +{ + return this->pd_context; +} + +UTL_ExceptList * +AST_Operation::exceptions (void) +{ + return this->pd_exceptions; +} + +// Narrowing. +IMPL_NARROW_METHODS2(AST_Operation, AST_Decl, UTL_Scope) +IMPL_NARROW_FROM_DECL(AST_Operation) +IMPL_NARROW_FROM_SCOPE(AST_Operation) diff --git a/TAO/TAO_IDL/ast/ast_predefined_type.cpp b/TAO/TAO_IDL/ast/ast_predefined_type.cpp new file mode 100644 index 00000000000..e98a2486abf --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_predefined_type.cpp @@ -0,0 +1,286 @@ +// $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. + +*/ + +// AST_PredefinedType nodes denote the various predefined types such +// as long, short, etc. that are available in IDL. Each AST_PredefinedType +// node has a field (the value of this field is from the enum +// AST_PredefinedType::PredefinedType) which denotes the specific predefined +// type that this node represents. There is only one node in the entire +// AST which represents each predefined type, such as long etc. + +#include "ast_predefined_type.h" +#include "ast_visitor.h" +#include "utl_identifier.h" +#include "global_extern.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_stdio.h" + +ACE_RCSID (ast, + ast_predefined_type, + "$Id$") + +AST_PredefinedType::AST_PredefinedType (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + AST_ConcreteType (), + pd_pt (PT_long) +{ +} + +AST_PredefinedType::AST_PredefinedType (PredefinedType t, + UTL_ScopedName *n) + : COMMON_Base (), + AST_Decl (AST_Decl::NT_pre_defined, + n, + true), + AST_Type (AST_Decl::NT_pre_defined, + n), + AST_ConcreteType (AST_Decl::NT_pre_defined, + n), + pd_pt (t) +{ + UTL_ScopedName *new_name = 0; + Identifier *id = 0; + + // Generate a new Scoped Name for us such that we belong to the CORBA + // namespace. + if (t == AST_PredefinedType::PT_void) + { + ACE_NEW (id, + Identifier (n->last_component ()->get_string ())); + + ACE_NEW (new_name, + UTL_ScopedName (id, + 0)); + } + else + { + ACE_NEW (id, + Identifier (idl_global->nest_orb () ? "NORB" : "CORBA")); + + ACE_NEW (new_name, + UTL_ScopedName (id, + 0)); + + UTL_ScopedName *conc_name = 0; + + switch (this->pt ()) + { + case AST_PredefinedType::PT_long: + ACE_NEW (id, + Identifier ("Long")); + break; + case AST_PredefinedType::PT_ulong: + ACE_NEW (id, + Identifier ("ULong")); + break; + case AST_PredefinedType::PT_short: + ACE_NEW (id, + Identifier ("Short")); + break; + case AST_PredefinedType::PT_ushort: + ACE_NEW (id, + Identifier ("UShort")); + break; + case AST_PredefinedType::PT_float: + ACE_NEW (id, + Identifier ("Float")); + break; + case AST_PredefinedType::PT_double: + ACE_NEW (id, + Identifier ("Double")); + break; + case AST_PredefinedType::PT_char: + ACE_NEW (id, + Identifier ("Char")); + break; + case AST_PredefinedType::PT_octet: + ACE_NEW (id, + Identifier ("Octet")); + break; + case AST_PredefinedType::PT_wchar: + ACE_NEW (id, + Identifier ("WChar")); + break; + case AST_PredefinedType::PT_boolean: + ACE_NEW (id, + Identifier ("Boolean")); + break; + case AST_PredefinedType::PT_longlong: + ACE_NEW (id, + Identifier ("LongLong")); + break; + case AST_PredefinedType::PT_ulonglong: + ACE_NEW (id, + Identifier ("ULongLong")); + break; + case AST_PredefinedType::PT_longdouble: + ACE_NEW (id, + Identifier ("LongDouble")); + break; + case AST_PredefinedType::PT_any: + ACE_NEW (id, + Identifier ("Any")); + break; + case AST_PredefinedType::PT_object: + ACE_NEW (id, + Identifier ("Object")); + break; + case AST_PredefinedType::PT_value: + ACE_NEW (id, + Identifier ("ValueBase")); + break; + case AST_PredefinedType::PT_pseudo: + ACE_NEW (id, + Identifier (n->last_component ()->get_string ())); + break; + default: + ACE_ERROR ((LM_ERROR, + "AST_PredefinedType - bad enum value\n")); + } + + ACE_NEW (conc_name, + UTL_ScopedName (id, + 0)); + + new_name->nconc (conc_name); + } + + // The repo id computation in the AST_Decl constructor can't + // be easily modified to work for predefined types. + ACE_CString repo_id = ACE_CString ("IDL:omg.org/CORBA/") + + id->get_string () + + ":" + + this->version (); + delete [] this->repoID_; + size_t len = repo_id.length (); + ACE_NEW (this->repoID_, + char[len + 1]); + this->repoID_[0] = '\0'; + ACE_OS::sprintf (this->repoID_, + "%s", + repo_id.c_str ()); + this->repoID_[len] = '\0'; + + this->set_name (new_name); +} + +AST_PredefinedType::~AST_PredefinedType (void) +{ +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_PredefinedType node to the ostream o. +void +AST_PredefinedType::dump (ACE_OSTREAM_TYPE &o) +{ + AST_Decl::dump (o); +} + +// Compute the size type of the node in question. +int +AST_PredefinedType::compute_size_type (void) +{ + switch (this->pd_pt) + { + case AST_PredefinedType::PT_any: + case AST_PredefinedType::PT_pseudo: + case AST_PredefinedType::PT_object: + this->size_type (AST_Type::VARIABLE); + break; + default: + this->size_type (AST_Type::FIXED); + break; + } + + return 0; +} + +int +AST_PredefinedType::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_predefined_type (this); +} + +void +AST_PredefinedType::destroy (void) +{ + this->AST_ConcreteType::destroy (); +} + +// Data accessors. + +AST_PredefinedType::PredefinedType +AST_PredefinedType::pt (void) +{ + return this->pd_pt; +} + +// Narrowing. +IMPL_NARROW_METHODS1(AST_PredefinedType, AST_ConcreteType) +IMPL_NARROW_FROM_DECL(AST_PredefinedType) diff --git a/TAO/TAO_IDL/ast/ast_recursive.cpp b/TAO/TAO_IDL/ast/ast_recursive.cpp new file mode 100644 index 00000000000..1603b184a0b --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_recursive.cpp @@ -0,0 +1,223 @@ +// $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. + +*/ + +// EXPLANATION: The CORBA spec says that the only legal use of recursive types is +// in a manifest sequence declared inside a struct or union whose base type is +// the struct or union. + +// ALGORITHM FOR CHECK: +// Sequences push a NULL on the scope stack to mark where in the scope nesting +// they appear. + +// - If the type is not a struct or union, return FALSE (legal use of type). +// - Otherwise check up the scope stack, looking for this base type. If we +// find a NULL return FALSE (legal use of type, since it is inside some +// sequence). If we find the type on the stack, return TRUE (illegal use +// since it was not bracketed by a sequence). If we don't find the base +// type nor a sequence, return FALSE (legal use, since we're not nested). + +#include "ast_union.h" +#include "utl_stack.h" +#include "global_extern.h" +#include "nr_extern.h" + +ACE_RCSID (ast, + ast_recursive, + "$Id$") + +bool +AST_illegal_interface_recursion (AST_Decl *t) +{ + // Can't be 0 since we know we have an interface or valuetype. + AST_Decl *d = 0; + + // If we encounter the argument in an enclosing scope, it's illegal. + for (UTL_ScopeStackActiveIterator i (idl_global->scopes ()); + !i.is_done (); + i.next ()) + { + d = ScopeAsDecl (i.item ()); + + // Exceptions cannot be recursive, but may contain a reference + // to the interface they are defined in. + if (d->node_type () == AST_Decl::NT_except) + { + return false; + } + + if (d == t) + { + return true; + } + } + + return false; +} + +bool +AST_illegal_recursive_type (AST_Decl *t) +{ + if (t == 0) + { + return false; + } + + AST_Decl::NodeType nt; + AST_Type *ut = AST_Type::narrow_from_decl (t); + + if (ut != 0) + { + ut = ut->unaliased_type (); + nt = ut->node_type (); + } + else + { + nt = t->node_type (); + } + + if (nt == AST_Decl::NT_interface) + { + // Check for interface->struct/union->....->interface nesting. +// return AST_illegal_interface_recursion (t); + } + else if (nt != AST_Decl::NT_struct && nt != AST_Decl::NT_union) + { + // Structs and unions fall through to the check below. + return false; // NOT ILLEGAL. + } + + bool check_for_struct = false; + bool check_for_union = false; + AST_Structure *st1 = 0; + AST_Union *un1 = 0; + + // Narrow the type appropriately so comparison will work. + if (t->node_type () == AST_Decl::NT_struct) + { + check_for_struct = true; + st1 = AST_Structure::narrow_from_decl (t); + + if (st1 == 0) + { + return false; // NOT ILLEGAL. + } + } + else if (t->node_type () == AST_Decl::NT_union) + { + check_for_union = true; + un1 = AST_Union::narrow_from_decl (t); + + if (un1 == 0) + { + return false; // NOT ILLEGAL. + } + } + + UTL_Scope *s = 0; + AST_Structure *st2 = 0; + AST_Union *un2 = 0; + + // OK, iterate up the stack. + for (UTL_ScopeStackActiveIterator i (idl_global->scopes ()); + !i.is_done (); + i.next ()) + { + s = i.item (); + + // If we hit a NULL we're done since it means that we're nested inside + // a sequence, where recursive types may be used. + if (s == 0) + { + return false; // NOT ILLEGAL. + } + + // OK, must check this scope. + if (s->scope_node_type () == AST_Decl::NT_struct + && check_for_struct == true) + { + st2 = AST_Structure::narrow_from_scope (s); + + if (st2 != 0 && st2 == st1) + { + return true; // ILLEGAL RECURSIVE TYPE USE. + } + } + else if (s->scope_node_type () == AST_Decl::NT_union + && check_for_union == true) + { + un2 = AST_Union::narrow_from_scope (s); + + if (un2 != 0 && un2 == un1) + { + return true; // ILLEGAL RECURSIVE TYPE USE. + } + } + } + + // No more scopes to check. This type was used legally. + return false; // NOT ILLEGAL. +} + diff --git a/TAO/TAO_IDL/ast/ast_redef.cpp b/TAO/TAO_IDL/ast/ast_redef.cpp new file mode 100644 index 00000000000..92043ccba80 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_redef.cpp @@ -0,0 +1,117 @@ +// $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 "ast_decl.h" + +ACE_RCSID (ast, + ast_redef, + "$Id$") + +// Return TRUE if the node d represents an IDL construct whose name +// can be redefined. +bool +can_be_redefined (AST_Decl *d) +{ + switch (d->node_type ()) + { + case AST_Decl::NT_module: + case AST_Decl::NT_interface: + case AST_Decl::NT_interface_fwd: + case AST_Decl::NT_valuetype: + case AST_Decl::NT_valuetype_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: + case AST_Decl::NT_const: + case AST_Decl::NT_except: + case AST_Decl::NT_argument: + case AST_Decl::NT_enum_val: + case AST_Decl::NT_string: + case AST_Decl::NT_wstring: + case AST_Decl::NT_array: + case AST_Decl::NT_sequence: + case AST_Decl::NT_union: + case AST_Decl::NT_union_fwd: + case AST_Decl::NT_struct: + case AST_Decl::NT_struct_fwd: + case AST_Decl::NT_enum: + case AST_Decl::NT_typedef: + case AST_Decl::NT_valuebox: + return true; + + case AST_Decl::NT_union_branch: + case AST_Decl::NT_field: + case AST_Decl::NT_attr: + case AST_Decl::NT_op: + case AST_Decl::NT_pre_defined: + case AST_Decl::NT_factory: + default: + return false; + } +} + diff --git a/TAO/TAO_IDL/ast/ast_root.cpp b/TAO/TAO_IDL/ast/ast_root.cpp new file mode 100644 index 00000000000..5c87e1983e9 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_root.cpp @@ -0,0 +1,275 @@ +// $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. + +*/ + +// AST_Root nodes represent the roots of ASTs. +// AST_Root is a subclass of AST_Module, and is defined to allow BEs +// to subclass it to associate their own information with an entire +// AST. + +#include "ast_root.h" +#include "ast_sequence.h" +#include "ast_string.h" +#include "ast_array.h" +#include "ast_visitor.h" +#include "utl_identifier.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_Memory.h" + +ACE_RCSID (ast, + ast_root, + "$Id$") + +AST_Root::AST_Root (void) + : COMMON_Base (), + AST_Decl (), + UTL_Scope (), + AST_Module () +{ +} + +AST_Root::AST_Root (UTL_ScopedName *n) + : COMMON_Base (), + AST_Decl (AST_Decl::NT_root, + n), + UTL_Scope (AST_Decl::NT_root), + AST_Module (n) +{ +} + +AST_Root::~AST_Root (void) +{ +} + +// Overrides the one in UTL_Scope - this one doesn't +// count the predefined types. +unsigned long +AST_Root::nmembers (void) +{ + unsigned long retval = 0; + + for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + if (si.item ()->node_type () == AST_Decl::NT_pre_defined) + { + continue; + } + + ++retval; + } + + return retval; +} + +// Add this AST_Sequence to the locally defined types in this scope. +AST_Sequence * +AST_Root::fe_add_sequence (AST_Sequence *t) +{ + if (t == 0) + { + return 0; + } + + Identifier *id = 0; + ACE_NEW_RETURN (id, + Identifier ("local type"), + 0); + + UTL_ScopedName *sn = 0; + ACE_NEW_RETURN (sn, + UTL_ScopedName (id, + 0), + 0); + + t->set_name (sn); + this->add_to_local_types (t); + return t; +} + +// Add this AST_String to the locally defined types in this scope. +AST_String * +AST_Root::fe_add_string (AST_String *t) +{ + if (t == 0) + { + return 0; + } + + Identifier *id = 0; + ACE_NEW_RETURN (id, + Identifier ("local type"), + 0); + + UTL_ScopedName *sn = 0; + ACE_NEW_RETURN (sn, + UTL_ScopedName (id, + 0), + 0); + + t->set_name (sn); + this->add_to_local_types (t); + return t; +} + +// Add this AST_Array to the locally defined types in this scope. +AST_Array * +AST_Root::fe_add_array (AST_Array *t) +{ + if (t == 0) + { + return 0; + } + + Identifier *id = 0; + ACE_NEW_RETURN (id, + Identifier ("local type"), + 0); + + UTL_ScopedName *sn = 0; + ACE_NEW_RETURN (sn, + UTL_ScopedName (id, + 0), + 0); + + t->set_name (sn); + this->add_to_local_types (t); + return t; +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_Root node to the ostream o. +void +AST_Root::dump (ACE_OSTREAM_TYPE &o) +{ + UTL_Scope::dump (o); +} + +int +AST_Root::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_root (this); +} + +void +AST_Root::destroy () +{ + long i = 0; + long j = 0; + AST_Decl *d = 0; + + // Just destroy and delete the non-predefined types in the + // scope, in case we are processing multiple IDL files. + // Final cleanup will be done in fini(). + for (i = this->pd_decls_used; i > 0; --i) + { + d = this->pd_decls[i - 1]; + + // We want to keep the predefined types we add to global + // scope around and not add them each time. + if (d->node_type () == AST_Decl::NT_pre_defined) + { + j = i; + break; + } + + d->destroy (); + delete d; + d = 0; + --this->pd_decls_used; + } + + // This array of pointers holds references, no need + // for destruction. The array itself will be cleaned + // up when AST_Root::fini() calls UTL_Scope::destroy (). + for (i = this->pd_referenced_used; i > j; --i) + { + this->pd_referenced[i - 1] = 0; + --this->pd_referenced_used; + } + + for (i = this->pd_name_referenced_used; i > j; --i) + { + Identifier *id = this->pd_name_referenced[i - 1]; + id->destroy (); + delete id; + id = 0; + --this->pd_name_referenced_used; + } +} + +void +AST_Root::fini (void) +{ + this->UTL_Scope::destroy (); + this->AST_Decl::destroy (); +} + +// Narrowing methods. +IMPL_NARROW_METHODS1(AST_Root, AST_Module) +IMPL_NARROW_FROM_DECL(AST_Root) +IMPL_NARROW_FROM_SCOPE(AST_Root) diff --git a/TAO/TAO_IDL/ast/ast_sequence.cpp b/TAO/TAO_IDL/ast/ast_sequence.cpp new file mode 100644 index 00000000000..6389a8b6f0a --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_sequence.cpp @@ -0,0 +1,264 @@ +// $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. + +*/ + +// AST_Sequence nodes represent IDL sequence declarations. +// AST_Sequence is a subclass of AST_ConcreteType. +// AST_Sequence nodes have a maximum size (an AST_Expression which +// must evaluate to a positive integer) and a base type (a subclass +// of AST_Type). + +#include "ast_sequence.h" +#include "ast_typedef.h" +#include "ast_expression.h" +#include "ast_visitor.h" +#include "utl_identifier.h" +#include "global_extern.h" +#include "ace/Log_Msg.h" +#include "ace/OS_Memory.h" +#include "ace/OS_NS_string.h" + +ACE_RCSID (ast, + ast_sequence, + "$Id$") + +AST_Sequence::AST_Sequence (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + AST_ConcreteType (), + pd_max_size (0), + pd_base_type (0), + owns_base_type_ (false) +{ + // A sequence data type is always VARIABLE. + this->size_type (AST_Type::VARIABLE); +} + +AST_Sequence::AST_Sequence (AST_Expression *ms, + AST_Type *bt, + UTL_ScopedName *n, + bool local, + bool abstract) + : COMMON_Base (bt->is_local () || local, + abstract), + AST_Decl (AST_Decl::NT_sequence, + n, + true), + AST_Type (AST_Decl::NT_sequence, + n), + AST_ConcreteType (AST_Decl::NT_sequence, + n), + pd_max_size (ms), + pd_base_type (bt), + owns_base_type_ (false) +{ + // Check if we are bounded or unbounded. An expression value of 0 means + // unbounded. + if (ms->ev ()->u.ulval == 0) + { + this->unbounded_ = true; + } + else + { + this->unbounded_ = false; + } + + // A sequence data type is always VARIABLE. + this->size_type (AST_Type::VARIABLE); + + AST_Decl::NodeType nt = bt->node_type (); + + if (AST_Decl::NT_array == nt || AST_Decl::NT_sequence == nt) + { + this->owns_base_type_ = true; + } +} + +AST_Sequence::~AST_Sequence (void) +{ +} + +// Public operations. + +bool +AST_Sequence::in_recursion (ACE_Unbounded_Queue<AST_Type *> &list) +{ + // We should calculate this only once. If it has already been + // done, just return it. + if (this->in_recursion_ != -1) + { + return this->in_recursion_; + } + + AST_Type *type = AST_Type::narrow_from_decl (this->base_type ()); + + if (!type) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%N:%l) AST_Sequence::") + ACE_TEXT ("in_recursion - ") + ACE_TEXT ("bad base type\n")), + 0); + } + + if (type->node_type () == AST_Decl::NT_typedef) + { + AST_Typedef *td = AST_Typedef::narrow_from_decl (type); + type = td->primitive_base_type (); + AST_Decl::NodeType nt = type->node_type (); + + if (nt != AST_Decl::NT_struct && nt != AST_Decl::NT_union) + { + return false; + } + } + + if (this->match_names (type, list)) + { + // They match. + this->in_recursion_ = 1; + idl_global->recursive_type_seen_ = true; + } + else + { + // Check the element type. + list.enqueue_tail (type); + this->in_recursion_ = type->in_recursion (list); + + if (this->in_recursion_ == 1) + { + idl_global->recursive_type_seen_ = true; + } + } + + return this->in_recursion_; +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_Sequence node to the ostream o. +void +AST_Sequence::dump (ACE_OSTREAM_TYPE &o) +{ + this->dump_i (o, "sequence <"); + this->pd_base_type->dump (o); + this->dump_i (o, ", "); + this->pd_max_size->dump (o); + this->dump_i (o, ">"); +} + +int +AST_Sequence::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_sequence (this); +} + +// Data accessors. + +AST_Expression * +AST_Sequence::max_size (void) +{ + return this->pd_max_size; +} + +AST_Type * +AST_Sequence::base_type (void) const +{ + return this->pd_base_type; +} + +bool +AST_Sequence::unbounded (void) const +{ + return this->unbounded_; +} + +bool +AST_Sequence::legal_for_primary_key (void) const +{ + return this->base_type ()->legal_for_primary_key (); +} + +void +AST_Sequence::destroy (void) +{ + if (this->owns_base_type_) + { + this->pd_base_type->destroy (); + delete this->pd_base_type; + this->pd_base_type = 0; + } + + this->pd_max_size->destroy (); + delete this->pd_max_size; + this->pd_max_size = 0; + + this->AST_ConcreteType::destroy (); +} + +// Narrowing. +IMPL_NARROW_METHODS1(AST_Sequence, AST_ConcreteType) +IMPL_NARROW_FROM_DECL(AST_Sequence) diff --git a/TAO/TAO_IDL/ast/ast_string.cpp b/TAO/TAO_IDL/ast/ast_string.cpp new file mode 100644 index 00000000000..35fed0da5a1 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_string.cpp @@ -0,0 +1,208 @@ +// $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. + +*/ + +// AST_String nodes represent IDL string declarations. +// AST_String is a subclass of AST_ConcreteType. +// AST_String nodes have a maximum size (an AST_Expression which must +// evaluate to a positive integer). + +#include "ast_string.h" +#include "ast_expression.h" +#include "ast_visitor.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_NS_string.h" +#include "utl_identifier.h" +#include "idl_defines.h" +#include "global_extern.h" + +ACE_RCSID (ast, + ast_string, + "$Id$") + +AST_String::AST_String (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + AST_ConcreteType (), + pd_max_size (0), + pd_width (sizeof (char)) +{ + // Always the case. + this->size_type (AST_Type::VARIABLE); +} + +AST_String::AST_String (AST_Decl::NodeType nt, + UTL_ScopedName *n, + AST_Expression *ms, + long wide) + : COMMON_Base (), + AST_Decl (nt, + n, + true), + AST_Type (nt, + n), + AST_ConcreteType (nt, + n), + pd_max_size (ms), + pd_width (wide) +{ + // Always the case. + this->size_type (AST_Type::VARIABLE); + + Identifier *id = 0; + UTL_ScopedName *new_name = 0; + UTL_ScopedName *conc_name = 0; + + ACE_NEW (id, + Identifier (this->width () == 1 ? "Char *" : "WChar *")); + + ACE_NEW (conc_name, + UTL_ScopedName (id, + 0)); + + ACE_NEW (id, + Identifier ("CORBA")); + + ACE_NEW (new_name, + UTL_ScopedName (id, + conc_name)); + + this->set_name (new_name); + + unsigned long bound = ms->ev ()->u.ulval; + + static char namebuf[NAMEBUFSIZE]; + static char boundbuf[NAMEBUFSIZE]; + ACE_OS::memset (namebuf, + '\0', + NAMEBUFSIZE); + ACE_OS::memset (boundbuf, + '\0', + NAMEBUFSIZE); + + if (bound) + { + ACE_OS::sprintf (boundbuf, + "_%ld", + bound); + } + + ACE_OS::sprintf (namebuf, + "CORBA_%sSTRING%s", + (wide == 1 ? "" : "W"), + boundbuf); + + this->flat_name_ = ACE::strnew (namebuf); +} + +AST_String::~AST_String (void) +{ +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_String node to the ostream o. +void +AST_String::dump (ACE_OSTREAM_TYPE &o) +{ + this->dump_i (o, "string <"); + this->pd_max_size->dump (o); + this->dump_i (o, ">"); +} + +int +AST_String::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_string (this); +} + +void +AST_String::destroy (void) +{ + this->pd_max_size->destroy (); + delete this->pd_max_size; + this->pd_max_size = 0; + + this->AST_ConcreteType::destroy (); +} + +// Data accessors. + +AST_Expression * +AST_String::max_size (void) +{ + return this->pd_max_size; +} + +long +AST_String::width (void) +{ + return this->pd_width; +} + +// Narrowing. +IMPL_NARROW_METHODS1(AST_String, AST_ConcreteType) +IMPL_NARROW_FROM_DECL(AST_String) diff --git a/TAO/TAO_IDL/ast/ast_structure.cpp b/TAO/TAO_IDL/ast/ast_structure.cpp new file mode 100644 index 00000000000..e5f83a1c0b8 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_structure.cpp @@ -0,0 +1,791 @@ +// $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. + +*/ + +// AST_Structure nodes denote IDL struct declarations. +// AST_Structure is a subclass of AST_ConcreteType and of UTL_Scope (the +// structure's fields are managed in a scope). + +#include "ast_union.h" +#include "ast_structure_fwd.h" +#include "ast_field.h" +#include "ast_enum.h" +#include "ast_enum_val.h" +#include "ast_visitor.h" +#include "utl_string.h" +#include "utl_err.h" +#include "utl_indenter.h" + +ACE_RCSID (ast, + ast_structure, + "$Id$") + +AST_Structure::AST_Structure (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + AST_ConcreteType (), + UTL_Scope (), + member_count_ (-1), + local_struct_ (-1), + fwd_decl_ (0) +{ +} + +AST_Structure::AST_Structure (UTL_ScopedName *n, + bool local, + bool abstract) + : COMMON_Base (local, + abstract), + AST_Decl (AST_Decl::NT_struct, + n), + AST_Type (AST_Decl::NT_struct, + n), + AST_ConcreteType (AST_Decl::NT_struct, + n), + UTL_Scope (AST_Decl::NT_struct), + member_count_ (-1), + local_struct_ (-1), + fwd_decl_ (0) +{ +} + +AST_Structure::AST_Structure (AST_Decl::NodeType nt, + UTL_ScopedName *n, + bool local, + bool abstract) + : COMMON_Base (local, + abstract), + AST_Decl (nt, + n), + AST_Type (nt, + n), + AST_ConcreteType (nt, + n), + UTL_Scope (nt), + member_count_ (-1), + local_struct_ (-1), + fwd_decl_ (0) +{ +} + +AST_Structure::~AST_Structure (void) +{ +} + +// Are we or the parameter node involved in any recursion? +bool +AST_Structure::in_recursion (ACE_Unbounded_Queue<AST_Type *> &list) +{ + // We should calculate this only once. If it has already been + // done, just return it. + if (this->in_recursion_ != -1) + { + return this->in_recursion_; + } + + // Proceed if the number of members in our scope is greater than 0. + if (this->nmembers () > 0) + { + ACE_Unbounded_Queue<AST_Type *> scope_list = list; + scope_list.enqueue_tail (this); + + // Initialize an iterator to iterate over our scope. + // Continue until each element is visited. + for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + AST_Field *field = AST_Field::narrow_from_decl (si.item ()); + + if (field == 0) + // This will be an enum value or other legitimate non-field + // member - in any case, no recursion. + { + continue; + } + + AST_Type *type = field->field_type (); + + if (type->node_type () == AST_Decl::NT_typedef) + { + AST_Typedef *td = AST_Typedef::narrow_from_decl (type); + type = td->primitive_base_type (); + } + + if (type == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%N:%l) AST_Structure::") + ACE_TEXT ("in_recursion - ") + ACE_TEXT ("bad field type\n")), + 0); + } + + if (type->in_recursion (scope_list)) + { + this->in_recursion_ = 1; + idl_global->recursive_type_seen_ = true; + return this->in_recursion_; + } + } + } + + // Not in recursion. + this->in_recursion_ = 0; + return this->in_recursion_; +} + +// Return the member count. +int +AST_Structure::member_count (void) +{ + if (this->member_count_ == -1) + { + this->compute_member_count (); + } + + return this->member_count_; +} + +size_t +AST_Structure::nfields (void) const +{ + return this->fields_.size (); +} + +int +AST_Structure::field (AST_Field **&result, + size_t slot) const +{ + return this->fields_.get (result, + slot); +} + +bool +AST_Structure::is_local (void) +{ + if (this->local_struct_ == -1) + { + if (this->is_local_) + { + this->local_struct_ = this->is_local_; + } + else + { + this->local_struct_ = 0; + + if (this->nmembers () > 0) + { + // Instantiate a scope iterator. + for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + if (si.item ()->is_local ()) + { + this->local_struct_ = true; + break; + } + } + } + } + } + + return this->local_struct_; +} + +int +AST_Structure::contains_wstring (void) +{ + if (this->contains_wstring_ == -1) + { + for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + if (si.item ()->contains_wstring () == 1) + { + this->contains_wstring_ = 1; + return this->contains_wstring_; + } + } + + this->contains_wstring_ = 0; + } + + return this->contains_wstring_; +} + +bool +AST_Structure::is_defined (void) +{ + return 0 == this->fwd_decl_ || this->fwd_decl_->is_defined (); +} + +bool +AST_Structure::legal_for_primary_key (void) const +{ + bool retval = true; + + if (!this->recursing_in_legal_pk_) + { + this->recursing_in_legal_pk_ = true; + + for (UTL_ScopeActiveIterator si (const_cast<AST_Structure *> (this), + UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + AST_Field *f = AST_Field::narrow_from_decl (si.item ()); + + if (f != 0 && !f->field_type ()->legal_for_primary_key ()) + { + retval = false; + break; + } + } + + this->recursing_in_legal_pk_ = false; + } + + return retval; +} + +AST_StructureFwd * +AST_Structure::fwd_decl (void) const +{ + return this->fwd_decl_; +} + +void +AST_Structure::fwd_decl (AST_StructureFwd *node) +{ + this->fwd_decl_ = node; +} + +// Private operations. + +// Add this AST_Field node (a field declaration) to this scope. +AST_Field * +AST_Structure::fe_add_field (AST_Field *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + AST_Type *ft = t->field_type (); + UTL_ScopedName *mru = ft->last_referenced_as (); + + if (mru != 0) + { + this->add_to_referenced (ft, + false, + mru->first_component ()); + } + + this->fields_.enqueue_tail (t); + + return t; +} + +// Add an AST_Structure node (a manifest struct type) to this scope. +AST_Structure * +AST_Structure::fe_add_structure (AST_Structure *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to local types. + this->add_to_local_types (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add an AST_Union node (a manifest union type) to this scope. +AST_Union * +AST_Structure::fe_add_union (AST_Union *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to local types. + this->add_to_local_types (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_Enum node (a manifest enum declaration) to this scope. +AST_Enum * +AST_Structure::fe_add_enum (AST_Enum *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to local types. + this->add_to_local_types (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_EnumVal node (an enumerator declaration) to this scope. +// This is done to conform to the C++ scoping rules which declare +// enumerators in the enclosing scope (in addition to declaring them +// in the enum itself). +AST_EnumVal * +AST_Structure::fe_add_enum_val (AST_EnumVal *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Compute total number of members. +int +AST_Structure::compute_member_count (void) +{ + this->member_count_ = 0; + + // If there are elements in this scope. + if (this->nmembers () > 0) + { + // Instantiate a scope iterator. + for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + ++this->member_count_; + } + } + + return 0; +} + +// Dump this AST_Structure node to the ostream o. +void +AST_Structure::dump (ACE_OSTREAM_TYPE &o) +{ + if (this->is_local ()) + { + this->dump_i (o, "(local) "); + } + + this->dump_i (o, "struct "); + AST_Decl::dump (o); + this->dump_i (o, " {\n"); + UTL_Scope::dump (o); + idl_global->indent ()->skip_to (o); + this->dump_i (o, "}"); +} + +// This serves for structs and unions. +void +AST_Structure::fwd_redefinition_helper (AST_Structure *&i, + UTL_Scope *s) +{ + if (i == 0) + { + return; + } + + // Fwd redefinition should be in the same scope, so local + // lookup is all that's needed. + AST_Decl *d = s->lookup_by_name_local (i->local_name (), + 0); + + AST_Structure *fd = 0; + + if (d != 0) + { + // Full definition must have the same prefix as the forward declaration. + if (ACE_OS::strcmp (i->prefix (), d->prefix ()) != 0) + { + idl_global->err ()->error1 (UTL_Error::EIDL_PREFIX_CONFLICT, + i); + + return; + } + + AST_Decl::NodeType nt = d->node_type (); + + // If this interface has been forward declared in a previous opening + // of the module it's defined in, the lookup will find the + // forward declaration. + if (nt == AST_Decl::NT_struct_fwd + || nt == AST_Decl::NT_union_fwd) + { + AST_StructureFwd *fwd_def = + AST_StructureFwd::narrow_from_decl (d); + + fd = fwd_def->full_definition (); + } + // In all other cases, the lookup will find an interface node. + else if (nt == AST_Decl::NT_struct + || nt == AST_Decl::NT_union) + { + fd = AST_Structure::narrow_from_decl (d); + } + + // Successful? + if (fd == 0) + { + // Should we give an error here? + // No, look in fe_add_interface. + } + // If it is a forward declared interface.. + else if (!fd->is_defined ()) + { + // Check if redefining in same scope. If a module is reopened, + // a new pointer in created, and the first term below will be + // true. In that case, the scoped names must be compared. + if (fd->defined_in () != s + && i->name ()->compare (fd->name ()) != 0) + { + idl_global->err ()->error2 (UTL_Error::EIDL_SCOPE_CONFLICT, + i, + fd); + } + // All OK, do the redefinition. + else + { + AST_Decl::NodeType fd_nt = fd->node_type (); + AST_Decl::NodeType i_nt = i->node_type (); + + // Only redefinition of the same kind. + if (i_nt != fd_nt) + { + idl_global->err ()->error2 (UTL_Error::EIDL_REDEF, + i, + fd); + return; + } + + fd->redefine (i); + AST_StructureFwd *fwd = fd->fwd_decl (); + + if (0 != fwd) + { + // So the fwd decl won't destroy us at cleanup time. + // Unlike interfaces, valuetypes and components, it's + // ok to do this here, since fwd declared structs + // and unions must be defined in the same translation + // unit. + fwd->set_as_defined (); + } + + // Use full definition node. + i->destroy (); + delete i; + i = fd; + } + } + } +} + +// This serves only for structs. It is overridden for unions. +void +AST_Structure::redefine (AST_Structure *from) +{ + // We've already checked for inconsistent prefixes. + this->prefix (from->prefix ()); + + this->set_defined_in (from->defined_in ()); + this->set_imported (idl_global->imported ()); + this->set_in_main_file (idl_global->in_main_file ()); + this->set_line (idl_global->lineno ()); + this->set_file_name (idl_global->filename ()->get_string ()); + this->ifr_added_ = from->ifr_added_; + this->ifr_fwd_added_ = from->ifr_fwd_added_; + this->fields_ = from->fields_; + this->member_count_ = from->member_count_; + this->local_struct_ = from->local_struct_; +} + +// Compute the size type of the node in question. +int +AST_Structure::compute_size_type (void) +{ + for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + // Get the next AST decl node. + AST_Decl *d = si.item (); + + if (d->node_type () == AST_Decl::NT_enum_val) + { + continue; + } + + AST_Field *f = AST_Field::narrow_from_decl (d); + AST_Type *t = f->field_type (); + + if (t != 0) + { + this->size_type (t->size_type ()); + + // While we're iterating, we might as well do this one too. + this->has_constructor (t->has_constructor ()); + } + else + { + ACE_DEBUG ((LM_DEBUG, + "WARNING (%N:%l) be_structure::compute_size_type - " + "narrow_from_decl returned 0\n")); + } + } + + return 0; +} + +int +AST_Structure::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_structure (this); +} + +void +AST_Structure::destroy (void) +{ + this->AST_ConcreteType::destroy (); + this->UTL_Scope::destroy (); +} + +// Narrowing. +IMPL_NARROW_METHODS2(AST_Structure, AST_ConcreteType, UTL_Scope) +IMPL_NARROW_FROM_DECL(AST_Structure) +IMPL_NARROW_FROM_SCOPE(AST_Structure) + diff --git a/TAO/TAO_IDL/ast/ast_structure_fwd.cpp b/TAO/TAO_IDL/ast/ast_structure_fwd.cpp new file mode 100644 index 00000000000..f6b87046559 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_structure_fwd.cpp @@ -0,0 +1,101 @@ +// $Id$ + +// AST_StructureFwd nodes denote forward declarations of IDL structs. +// AST_StructureFwd nodes have a field containing the full declaration +// of the struct, which is initialized when that declaration is +// encountered. + +#include "ast_structure_fwd.h" +#include "ast_structure.h" +#include "ast_visitor.h" +#include "utl_identifier.h" + +ACE_RCSID( ast, + ast_structure_fwd, + "$Id$") + +AST_StructureFwd::AST_StructureFwd (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + pd_full_definition (0), + is_defined_ (false) +{ +} + +AST_StructureFwd::AST_StructureFwd (AST_Structure *full_defn, + UTL_ScopedName *n) + : COMMON_Base (), + AST_Decl (AST_Decl::NT_struct_fwd, + n), + AST_Type (AST_Decl::NT_struct_fwd, + n), + pd_full_definition (full_defn), + is_defined_ (false) +{ +} + +AST_StructureFwd::~AST_StructureFwd (void) +{ +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_StructureFwd node to the ostream o. +void +AST_StructureFwd::dump (ACE_OSTREAM_TYPE &o) +{ + this->dump_i (o, "struct "); + this->local_name ()->dump (o); +} + +int +AST_StructureFwd::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_structure_fwd (this); +} + +// Data accessors. + +AST_Structure * +AST_StructureFwd::full_definition (void) +{ + return this->pd_full_definition; +} + +void +AST_StructureFwd::set_full_definition (AST_Structure *nfd) +{ + delete this->pd_full_definition; + this->pd_full_definition = 0; + this->pd_full_definition = nfd; +} + +bool +AST_StructureFwd::is_defined (void) +{ + return this->is_defined_; +} + +void +AST_StructureFwd::set_as_defined (void) +{ + this->is_defined_ = true; +} + +void +AST_StructureFwd::destroy (void) +{ + if (!this->is_defined_ && 0 != this->pd_full_definition) + { + this->pd_full_definition->destroy (); + delete this->pd_full_definition; + this->pd_full_definition = 0; + } + + this->AST_Type::destroy (); +} + +// Narrowing methods. +IMPL_NARROW_METHODS1 (AST_StructureFwd, AST_Type) +IMPL_NARROW_FROM_DECL (AST_StructureFwd) diff --git a/TAO/TAO_IDL/ast/ast_type.cpp b/TAO/TAO_IDL/ast/ast_type.cpp new file mode 100644 index 00000000000..58624791838 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_type.cpp @@ -0,0 +1,565 @@ +// $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. + +*/ + +// AST_Type is the base class for all AST classes which represent +// IDL type constructs. + +#include "ast_type.h" +#include "ast_typedef.h" +#include "ast_visitor.h" +#include "utl_identifier.h" +#include "idl_defines.h" +#include "nr_extern.h" +#include "ace/Log_Msg.h" +#include "ace/OS_NS_string.h" +#include "ace/OS_NS_stdio.h" +#include "ace/OS_Memory.h" + +ACE_RCSID (ast, + ast_type, + "$Id$") + +AST_Type::AST_Type (void) + : COMMON_Base (), + AST_Decl (), + ifr_added_ (0), + ifr_fwd_added_ (0), + size_type_ (AST_Type::SIZE_UNKNOWN), + has_constructor_ (0), + nested_type_name_ (0), + in_recursion_ (-1), + recursing_in_legal_pk_ (false) +{ +} + +AST_Type::AST_Type (AST_Decl::NodeType nt, + UTL_ScopedName *n) + : COMMON_Base (), + AST_Decl (nt, + n), + ifr_added_ (0), + ifr_fwd_added_ (0), + size_type_ (AST_Type::SIZE_UNKNOWN), + has_constructor_ (0), + nested_type_name_ (0), + in_recursion_ (-1), + recursing_in_legal_pk_ (false) +{ +} + +AST_Type::~AST_Type (void) +{ +} + +// Public operations. + +// Return our size type. +AST_Type::SIZE_TYPE +AST_Type::size_type (void) +{ + if (this->size_type_ == AST_Type::SIZE_UNKNOWN) + { + (void) this->compute_size_type (); + } + + return this->size_type_; +} + +// Set our size type and that of all our ancestors. +void +AST_Type::size_type (AST_Type::SIZE_TYPE st) +{ + // Precondition - you cannot set somebody's sizetype to unknown. + ACE_ASSERT (st != AST_Type::SIZE_UNKNOWN); + + // Size type can be VARIABLE or FIXED. + if (this->size_type_ == AST_Type::SIZE_UNKNOWN) // not set yet + { + this->size_type_ = st; // set it + } + else if ((this->size_type_ == AST_Type::FIXED) + && (st == AST_Type::VARIABLE)) + { + // Once we are VARIABLE, we cannot be FIXED. But if we were FIXED and then + // get overwritten to VARIABLE, it is fine. Such a situation occurs only + // when setting the sizes of structures and unions. + this->size_type_ = st; + } +} + +// Compute the size type of the node in question +int +AST_Type::compute_size_type (void) +{ + return 0; +} + +bool +AST_Type::in_recursion (ACE_Unbounded_Queue<AST_Type *> &) +{ + // By default we are not involved in recursion. + return 0; +} + +bool +AST_Type::is_defined (void) +{ + // AST_Interface, AST_Structure, and AST_Union will + // override this, as will AST_InterfaceFwd, etc. + return 1; +} + +bool +AST_Type::ifr_added (void) +{ + return this->ifr_added_; +} + +void +AST_Type::ifr_added (bool val) +{ + this->ifr_added_ = val; +} + +bool +AST_Type::ifr_fwd_added (void) +{ + return this->ifr_fwd_added_; +} + +void +AST_Type::ifr_fwd_added (bool val) +{ + this->ifr_fwd_added_ = val; +} + +bool +AST_Type::has_constructor (void) +{ + return this->has_constructor_; +} + +void +AST_Type::has_constructor (bool value) +{ + // Similarly to be_decl::size_type_, once this + // gets set to true, we don't want it to + // change back. + if (this->has_constructor_ == 0) + { + this->has_constructor_ = value; + } +} + +// This code works. However, whether we should generate the +// ACE_NESTED_CLASS macro or not should be based on an option to the +// compiler. The previous version generated a relative path. +// This version always generates ACE_NESTED_CLASS, (leave ace/ACE.h and friends +// do the porting) +// +// Caution: returns the same buffer pointer even if the contents may change +// in the next call. (return std::string anyone?) +// +// Return the type name using the ACE_NESTED_CLASS macro + +const char * +AST_Type::nested_type_name (AST_Decl *use_scope, + const char *suffix, + const char *prefix) +{ + return this->nested_name (this->local_name ()->get_string (), + this->full_name (), + use_scope, + suffix, + prefix); +} + +AST_Type * +AST_Type::unaliased_type (void) +{ + AST_Type *t = this; + AST_Typedef *td = 0; + AST_Decl::NodeType nt = this->node_type (); + + while (nt == AST_Decl::NT_typedef) + { + td = AST_Typedef::narrow_from_decl (t); + t = td->base_type (); + nt = t->node_type (); + } + + return t; +} + +bool +AST_Type::legal_for_primary_key (void) const +{ + return true; +} + +// This is the real thing used by the method above. +const char * +AST_Type::nested_name (const char* local_name, + const char* full_name, + AST_Decl *use_scope, + const char *suffix, + const char *prefix) +{ + // Some compilers do not like generating a fully scoped name for a type that + // was defined in the same enclosing scope in which it was defined. For such, + // we emit a macro defined in the ACE library. + // + + // The tricky part here is that it is not enough to check if the + // typename we are using was defined in the current scope. But we + // need to ensure that it was not defined in any of our ancestor + // scopes as well. If that is the case, then we can generate a fully + // scoped name for that type, else we use the ACE_NESTED_CLASS macro. + + // Thus we need some sort of relative name to be generated. + + if (this->nested_type_name_ == 0) + { + ACE_NEW_RETURN (this->nested_type_name_, + char[NAMEBUFSIZE], + 0); + } + + // Our defining scope. + AST_Decl *def_scope = 0; + + // Hold the fully scoped name. + char def_name [NAMEBUFSIZE]; + char use_name [NAMEBUFSIZE]; + + // These point to the prev, curr and next component in the scope. + char *def_curr = def_name; + char *def_next = 0; + char *use_curr = use_name; + char *use_next = 0; + + // How many chars to compare. + int len_to_match = 0; + + // Initialize the buffers. + ACE_OS::memset (this->nested_type_name_, + '\0', + NAMEBUFSIZE); + + ACE_OS::memset (def_name, + '\0', + NAMEBUFSIZE); + + ACE_OS::memset (use_name, + '\0', + NAMEBUFSIZE); + + // Traverse every component of the def_scope and use_scope beginning at the + // root and proceeding towards the leaf trying to see if the components + // match. Continue until there is a match and keep accumulating the path + // traversed. This forms the first argument to the ACE_NESTED_CLASS + // macro. Whenever there is no match, the remaining components of the + // def_scope form the second argument. + + UTL_Scope *s = this->defined_in (); + + def_scope = s ? ScopeAsDecl (s) : 0; + + if (def_scope + && def_scope->node_type () != AST_Decl::NT_root + && use_scope) + // If both scopes exist and that we are not in the root scope. + { + ACE_OS::strcpy (def_name, + def_scope->full_name ()); + + ACE_OS::strcpy (use_name, + use_scope->full_name ()); + + // Find the first occurrence of a :: and advance + // the next pointers accordingly. + def_next = ACE_OS::strstr (def_curr, "::"); + use_next = ACE_OS::strstr (use_curr, "::"); + + // If the scopes are identical, don't supply them. + if (ACE_OS::strcmp (def_name, use_name) == 0) + { + if (prefix != 0) + { + ACE_OS::strcat (this->nested_type_name_, + prefix); + } + + ACE_OS::strcat (this->nested_type_name_, + local_name); + if (suffix != 0) + { + ACE_OS::strcat (this->nested_type_name_, + suffix); + } + + return this->nested_type_name_; + } + + if (def_next != 0) + { + len_to_match = + static_cast<int> (ACE_OS::strlen (def_curr)) - + static_cast<int> (ACE_OS::strlen (def_next)); + } + else + { + len_to_match = static_cast<int> (ACE_OS::strlen (def_curr)); + } + + if (use_next != 0) + { + const int len = + static_cast<int> (ACE_OS::strlen (use_curr)) - + static_cast<int> (ACE_OS::strlen (use_next)); + + if (len > len_to_match) + { + len_to_match = len; + } + } + else + { + const int len = static_cast<int> (ACE_OS::strlen (use_curr)); + + if (len > len_to_match) + { + len_to_match = len; + } + } + + if (ACE_OS::strncmp (def_curr, + use_curr, + len_to_match) + == 0) + { + // Initialize the first argument. + ACE_OS::strncat (this->nested_type_name_, + def_curr, + len_to_match); + + // Shift the current scopes to the next level. + def_curr = (def_next ? (def_next + 2) : 0); // Skip the :: + use_curr = (use_next ? (use_next + 2) : 0); // Skip the :: + + while (def_curr && use_curr) + { + // Find the first occurrence of a :: and advance the + // next pointers accordingly. + def_next = ACE_OS::strstr (def_curr, "::"); + use_next = ACE_OS::strstr (use_curr, "::"); + + if (def_next != 0) + { + len_to_match = + static_cast<int> (ACE_OS::strlen (def_curr)) - + static_cast<int> (ACE_OS::strlen (def_next)); + } + else + { + len_to_match = static_cast<int> (ACE_OS::strlen (def_curr)); + } + + if (use_next != 0) + { + int len = + static_cast<int> (ACE_OS::strlen (use_curr)) - + static_cast<int> (ACE_OS::strlen (use_next)); + + if (len > len_to_match) + { + len_to_match = len; + } + } + else + { + const int len = static_cast<int> (ACE_OS::strlen (use_curr)); + + if (len > len_to_match) + { + len_to_match = len; + } + } + + if (ACE_OS::strncmp (def_curr, + use_curr, + len_to_match) + == 0) + { + // They have same prefix, append to arg1. + ACE_OS::strcat (this->nested_type_name_, + "::"); + + ACE_OS::strncat (this->nested_type_name_, + def_curr, + len_to_match); + + def_curr = (def_next ? (def_next + 2) : 0); // Skip the :: + use_curr = (use_next ? (use_next + 2) : 0); // Skip the :: + } + else + { + // No match. This is the end of the first argument. Get out + // of the loop as no more comparisons are necessary. + break; + } + } + + // Start the 2nd argument of the macro. + ACE_OS::strcat (this->nested_type_name_, "::"); + + // Copy the remaining def_name (if any are left). + if (def_curr != 0) + { + ACE_OS::strcat (this->nested_type_name_, + def_curr); + + ACE_OS::strcat (this->nested_type_name_, + "::"); + } + + // Append our local name. + if (prefix != 0) + { + ACE_OS::strcat (this->nested_type_name_, prefix); + } + + ACE_OS::strcat (this->nested_type_name_, + local_name); + + if (suffix != 0) + { + ACE_OS::strcat (this->nested_type_name_, + suffix); + } + + return this->nested_type_name_; + } // End of if the root prefixes match. + } + + // Otherwise just emit our full_name. + if (prefix != 0) + { + ACE_OS::strcat (this->nested_type_name_, prefix); + } + + ACE_OS::strcat (this->nested_type_name_, + full_name); + + if (suffix != 0) + { + ACE_OS::strcat (this->nested_type_name_, + suffix); + } + + return this->nested_type_name_; +} + +bool +AST_Type::match_names (AST_Type *t, ACE_Unbounded_Queue<AST_Type *> &list) +{ + for (ACE_Unbounded_Queue_Iterator<AST_Type *> iter (list); + !iter.done (); + (void) iter.advance ()) + { + // Queue element. + AST_Type **temp; + + (void) iter.next (temp); + + if (!ACE_OS::strcmp (t->full_name (), + (*temp)->full_name ())) + { + return true; + } + } + + return false; +} + +int +AST_Type::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_type (this); +} + +void +AST_Type::destroy (void) +{ + delete [] this->nested_type_name_; + this->nested_type_name_ = 0; + + this->AST_Decl::destroy (); +} + +// Narrowing. +IMPL_NARROW_METHODS1(AST_Type, AST_Decl) +IMPL_NARROW_FROM_DECL(AST_Type) diff --git a/TAO/TAO_IDL/ast/ast_typedef.cpp b/TAO/TAO_IDL/ast/ast_typedef.cpp new file mode 100644 index 00000000000..515bebb07be --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_typedef.cpp @@ -0,0 +1,219 @@ +// $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. + +*/ + +// AST_Typedef nodes represent an IDL typedef statement. +// AST_Typedef is a subclass of AST_Decl (it is not a type, +// but instead is a type renaming). +// AST_Typedef nodes have a base type (a subclass of AST_Type) +// and a name (an UTL_ScopedName). + +#include "ast_typedef.h" +#include "ast_visitor.h" +#include "utl_identifier.h" + +#include "ace/Log_Msg.h" + +ACE_RCSID (ast, + ast_typedef, + "$Id$") + +AST_Typedef::AST_Typedef (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + pd_base_type (0), + owns_base_type_ (false) +{ +} + +AST_Typedef::AST_Typedef (AST_Type *bt, + UTL_ScopedName *n, + bool local, + bool abstract) + : COMMON_Base (bt->is_local () || local, + abstract), + AST_Decl (AST_Decl::NT_typedef, + n), + AST_Type (AST_Decl::NT_typedef, + n), + pd_base_type (bt), + owns_base_type_ (false) +{ + AST_Decl::NodeType nt = bt->node_type (); + + if (AST_Decl::NT_array == nt || AST_Decl::NT_sequence == nt) + { + this->owns_base_type_ = true; + } +} + +AST_Typedef::~AST_Typedef (void) +{ +} + +// Given a typedef node, traverse the chain of base types until they are no +// more typedefs, and return that most primitive base type. +AST_Type * +AST_Typedef::primitive_base_type (void) const +{ + AST_Type *d = const_cast<AST_Typedef *> (this); + AST_Typedef *temp = 0; + + while (d && d->node_type () == AST_Decl::NT_typedef) + { + temp = AST_Typedef::narrow_from_decl (d); + d = AST_Type::narrow_from_decl (temp->base_type ()); + } + + return d; +} + +// Redefinition of inherited virtual operations. + +AST_Type * +AST_Typedef::base_type (void) const +{ + return this->pd_base_type; +} + +bool +AST_Typedef::legal_for_primary_key (void) const +{ + return this->primitive_base_type ()->legal_for_primary_key (); +} + +bool +AST_Typedef::is_local (void) +{ + return this->pd_base_type->is_local (); +} + +// Dump this AST_Typedef node to the ostream o. +void +AST_Typedef::dump (ACE_OSTREAM_TYPE&o) +{ + if (this->is_local ()) + { + this->dump_i (o, "(local) "); + } + else + { + this->dump_i (o, "(abstract) "); + } + + this->dump_i (o, "typedef "); + this->pd_base_type->dump (o); + this->dump_i (o, " "); + this->local_name ()->dump (o); +} + +// Compute the size type of the node in question. +int +AST_Typedef::compute_size_type (void) +{ + AST_Type *type = this->base_type (); + + if (type == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_typedef::compute_size_type - " + "bad base type\n"), + -1); + } + + // Our size type is the same as our type. + this->size_type (type->size_type ()); + + // While we're here, take care of has_constructor. + this->has_constructor (type->has_constructor ()); + + return 0; +} + +int +AST_Typedef::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_typedef (this); +} + +void +AST_Typedef::destroy (void) +{ + if (this->owns_base_type_) + { + this->pd_base_type->destroy (); + delete this->pd_base_type; + this->pd_base_type = 0; + } + + this->AST_Type::destroy (); +} + +// Data accessors. + +// Narrowing. +IMPL_NARROW_METHODS1(AST_Typedef, AST_Type) +IMPL_NARROW_FROM_DECL(AST_Typedef) diff --git a/TAO/TAO_IDL/ast/ast_union.cpp b/TAO/TAO_IDL/ast/ast_union.cpp new file mode 100644 index 00000000000..498fa278ac7 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_union.cpp @@ -0,0 +1,1263 @@ +// $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. + +*/ + +// AST_Union nodes represent IDL union declarations. +// AST_Union is a subclass of AST_ConcreteType and of UTL_Scope (the +// union branches are managed in a scope). +// AST_Union nodes have a discriminator type (a subclass of AST_ConcreteType), +// a name (an UTL_ScopedName) and a field denoting the discriminator type if +// it is a primitive type (the value of this field is from the union +// AST_Expression::ExprType and serves as a cache). This field is used +// to compute coercions for labels based on the expected discriminator type. + +#include "ast_union.h" +#include "ast_union_branch.h" +#include "ast_union_label.h" +#include "ast_field.h" +#include "ast_predefined_type.h" +#include "ast_enum.h" +#include "ast_enum_val.h" +#include "ast_visitor.h" +#include "utl_err.h" +#include "utl_identifier.h" +#include "utl_indenter.h" +#include "global_extern.h" + +// FUZZ: disable check_for_streams_include +#include "ace/streams.h" + +ACE_RCSID (ast, + ast_union, + "$Id$") + +AST_Union::AST_Union (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + AST_ConcreteType (), + UTL_Scope (), + AST_Structure (), + default_index_ (-2) +{ +} + +AST_Union::AST_Union (AST_ConcreteType *dt, + UTL_ScopedName *n, + bool local, + bool abstract) + : COMMON_Base (local, + abstract), + AST_Decl (AST_Decl::NT_union, + n), + AST_Type (AST_Decl::NT_union, + n), + AST_ConcreteType (AST_Decl::NT_union, + n), + UTL_Scope (AST_Decl::NT_union), + AST_Structure (n, + local, + abstract), + default_index_ (-2) +{ + this->default_value_.computed_ = -2; + + AST_PredefinedType *pdt = 0; + + if (dt == 0) + { + this->pd_disc_type = 0; + this->pd_udisc_type = AST_Expression::EV_none; + return; + } + + // If the discriminator type is a predefined type + // then install the equivalent coercion target type in + // the pd_udisc_type field. + if (dt->node_type () == AST_Decl::NT_pre_defined) + { + pdt = AST_PredefinedType::narrow_from_decl (dt); + + if (pdt == 0) + { + this->pd_disc_type = 0; + this->pd_udisc_type = AST_Expression::EV_none; + return; + } + + pd_disc_type = dt; + + switch (pdt->pt ()) + { + case AST_PredefinedType::PT_long: + this->pd_udisc_type = AST_Expression::EV_long; + break; + case AST_PredefinedType::PT_ulong: + this->pd_udisc_type = AST_Expression::EV_ulong; + break; + case AST_PredefinedType::PT_short: + this->pd_udisc_type = AST_Expression::EV_short; + break; + case AST_PredefinedType::PT_ushort: + this->pd_udisc_type = AST_Expression::EV_ushort; + break; + case AST_PredefinedType::PT_char: + this->pd_udisc_type = AST_Expression::EV_char; + break; + case AST_PredefinedType::PT_wchar: + this->pd_udisc_type = AST_Expression::EV_wchar; + break; + case AST_PredefinedType::PT_octet: + this->pd_udisc_type = AST_Expression::EV_octet; + break; + case AST_PredefinedType::PT_boolean: + this->pd_udisc_type = AST_Expression::EV_bool; + break; + default: + this->pd_udisc_type = AST_Expression::EV_none; + this->pd_disc_type = 0; + break; + } + } + else if (dt->node_type () == AST_Decl::NT_enum) + { + this->pd_udisc_type = AST_Expression::EV_enum; + this->pd_disc_type = dt; + } + else + { + this->pd_udisc_type = AST_Expression::EV_none; + this->pd_disc_type = 0; + } + + if (this->pd_disc_type == 0) + { + idl_global->err ()->error2 (UTL_Error::EIDL_DISC_TYPE, + this, + dt); + } +} + +AST_Union::~AST_Union (void) +{ +} + +// Public operations. + +void +AST_Union::redefine (AST_Structure *from) +{ + AST_Union *u = AST_Union::narrow_from_decl (from); + + if (u == 0) + { + idl_global->err ()->redef_error (from->local_name ()->get_string (), + this->local_name ()->get_string ()); + return; + } + + // Copy over all the base class members. + this->AST_Structure::redefine (from); + + this->pd_disc_type = u->pd_disc_type; + this->pd_udisc_type = u->pd_udisc_type; + this->default_index_ = u->default_index_; + this->default_value_ = u->default_value_; +} + +// Return the default_index. +int +AST_Union::default_index (void) +{ + if (this->default_index_ == -2) + { + this->compute_default_index (); + } + + return this->default_index_; +} + +// Are we or the parameter node involved in any recursion? +bool +AST_Union::in_recursion (ACE_Unbounded_Queue<AST_Type *> &list) +{ + // Proceed if the number of members in our scope is greater than 0. + if (this->nmembers () > 0) + { + ACE_Unbounded_Queue<AST_Type *> scope_list = list; + scope_list.enqueue_tail (this); + + // Initialize an iterator to iterate thru our scope. + // Continue until each element is visited. + for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + AST_UnionBranch *field = + AST_UnionBranch::narrow_from_decl (si.item ()); + + if (field == 0) + // This will be an enum value or other legitimate non-field + // member - in any case, no recursion. + { + continue; + } + + AST_Type *type = field->field_type (); + + if (type->node_type () == AST_Decl::NT_typedef) + { + AST_Typedef *td = AST_Typedef::narrow_from_decl (type); + type = td->primitive_base_type (); + } + + if (type == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%N:%l) AST_Union::") + ACE_TEXT ("in_recursion - ") + ACE_TEXT ("bad field type\n")), + 0); + } + + if (type->in_recursion (scope_list)) + { + this->in_recursion_ = 1; + idl_global->recursive_type_seen_ = true; + return this->in_recursion_; + } + } + } + + // Not in recursion. + this->in_recursion_ = 0; + return this->in_recursion_; +} + +// Look up the default branch in union. +AST_UnionBranch * +AST_Union::lookup_default (void) +{ + AST_UnionBranch *b = 0; + AST_Decl *d = 0; + + for (UTL_ScopeActiveIterator i (this, UTL_Scope::IK_both); + !i.is_done(); + i.next ()) + { + d = i.item (); + + if (d->node_type () == AST_Decl::NT_union_branch) + { + b = AST_UnionBranch::narrow_from_decl (d); + + if (b == 0) + { + continue; + } + + if (b->label () != 0 + && b->label ()->label_kind () == AST_UnionLabel::UL_default) + { + idl_global->err ()->error2 (UTL_Error::EIDL_MULTIPLE_BRANCH, + this, + b); + return b; + } + } + } + + return 0; +} + +// Look up a branch by label. +AST_UnionBranch * +AST_Union::lookup_label (AST_UnionBranch *b) +{ + AST_UnionLabel *label = b->label (); + AST_Expression *lv = label->label_val (); + + if (label->label_val () == 0) + { + return b; + } + + AST_Decl *d = 0; + AST_UnionBranch *fb = 0; + + lv->set_ev (lv->coerce (this->pd_udisc_type)); + + if (lv->ev () == 0) + { + idl_global->err ()->eval_error (lv); + return b; + } + + for (UTL_ScopeActiveIterator i (this, UTL_Scope::IK_decls); + !i.is_done(); + i.next ()) + { + d = i.item (); + + if (d->node_type () == AST_Decl::NT_union_branch) + { + fb = AST_UnionBranch::narrow_from_decl (d); + + if (fb == 0) + { + continue; + } + + if (fb->label() != 0 + && fb->label ()->label_kind () == AST_UnionLabel::UL_label + && fb->label ()->label_val ()->compare (lv)) + { + idl_global->err ()->error2 (UTL_Error::EIDL_MULTIPLE_BRANCH, + this, + b); + return b; + } + } + } + + return 0; +} + +// Look up a branch in an enum which is the discriminator type for this +// union, based on the label value which must be an enumerator in that +// enum. +AST_UnionBranch * +AST_Union::lookup_enum (AST_UnionBranch *b) +{ + AST_UnionLabel *label = b->label(); + AST_Expression *lv = label->label_val (); + AST_Enum *e = AST_Enum::narrow_from_decl (this->pd_disc_type); + AST_Decl *d = 0; + AST_UnionBranch *fb = 0; + + if (e == 0) + { + return 0; + } + + if (lv == 0) + { + return b; + } + + // Expecting a symbol label. + if (lv->ec () != AST_Expression::EC_symbol) + { + idl_global->err ()->enum_val_expected (this, + label); + return b; + } + + // See if the symbol defines a constant in the discriminator enum. + UTL_ScopedName *sn = lv->n (); + d = e->lookup_by_name (sn, + true); + + if (d == 0 || d->defined_in () != e) + { + idl_global->err ()->enum_val_lookup_failure (this, + e, + sn); + return b; + } + + // OK, now see if this symbol is already used as the label of + // some other branch. + for (UTL_ScopeActiveIterator i (this, UTL_Scope::IK_decls); + !i.is_done(); + i.next ()) + { + d = i.item (); + + if (d->node_type () == AST_Decl::NT_union_branch) + { + fb = AST_UnionBranch::narrow_from_decl (d); + + if (fb == 0) + { + continue; + } + + if (fb->label() != 0 + && fb->label ()->label_kind () == AST_UnionLabel::UL_label + && fb->label ()->label_val ()->compare (lv)) + { + idl_global->err ()->error2 (UTL_Error::EIDL_MULTIPLE_BRANCH, + this, + b); + return b; + } + } + } + + return 0; +} + +// Look up a branch by value. This is the top level branch label resolution +// entry point. It dispatches to the right lookup function depending on the +// union discriminator type. +AST_UnionBranch * +AST_Union::lookup_branch (AST_UnionBranch *branch) +{ + AST_UnionLabel *label = 0; + + if (branch != 0) + { + label = branch->label (); + } + + if (label != 0) + { + if (label->label_kind () == AST_UnionLabel::UL_default) + { + return this->lookup_default (); + } + + if (this->pd_udisc_type == AST_Expression::EV_enum) + { + // CONVENTION: indicates enum discriminant. + return this->lookup_enum (branch); + } + + return this->lookup_label (branch); + } + + return 0; +} + +// Return the default value. +int +AST_Union::default_value (AST_Union::DefaultValue &dv) +{ + if (this->default_value_.computed_ == -2) + { + // We need to compute it. + if (this->compute_default_value () == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%N:%l) AST_Union::") + ACE_TEXT ("default_value - ") + ACE_TEXT ("Error computing ") + ACE_TEXT ("default value\n")), + -1); + } + } + + dv = this->default_value_; + return 0; +} + +// Determine the default value (if any). +int +AST_Union::compute_default_value (void) +{ + // Check if we really need a default value. This will be true if there is an + // explicit default case OR if an implicit default exists because not all + // values of the discriminant type are covered by the cases. + + // Compute the total true "case" labels i.e., exclude the "default" case. + int total_case_members = 0; + + // Instantiate a scope iterator. + for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + // Get the next AST decl node. + AST_UnionBranch *ub = + AST_UnionBranch::narrow_from_decl (si.item ()); + + if (ub != 0) + { + // If the label is a case label, increment by 1. + for (unsigned long i = 0; i < ub->label_list_length (); ++i) + { + if (ub->label (i)->label_kind () == AST_UnionLabel::UL_label) + { + ++total_case_members; + } + } + } + } + + // Check if the total_case_members cover the entire + // range of values that are permitted by the discriminant type. If they do, + // then a default value is not necessary. However, if such an explicit + // default case is provided, it must be flagged off as an error. Our + // front-end is not able to handle such a case since it is a semantic error + // and not a syntax error. Such an error is caught here. + + switch (this->udisc_type ()) + { + case AST_Expression::EV_short: + case AST_Expression::EV_ushort: + if (total_case_members == ACE_UINT16_MAX + 1) + { + this->default_value_.computed_ = 0; + } + + break; + case AST_Expression::EV_long: + case AST_Expression::EV_ulong: + if ((unsigned int) total_case_members > ACE_UINT32_MAX) + { + this->default_value_.computed_ = 0; + } + + break; + case AST_Expression::EV_longlong: + case AST_Expression::EV_ulonglong: + // Error for now. + this->default_value_.computed_ = -1; + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("(%N:%l) AST_Union::compute_default_value ") + ACE_TEXT ("- unimplemented discriminant type ") + ACE_TEXT ("(longlong or ulonglong)\n") + ), + -1 + ); + ACE_NOTREACHED (break;) + case AST_Expression::EV_char: + if (total_case_members == ACE_OCTET_MAX + 1) + { + this->default_value_.computed_ = 0; + } + + break; + case AST_Expression::EV_wchar: + if (total_case_members == ACE_WCHAR_MAX + 1) + { + this->default_value_.computed_ = 0; + } + + break; + case AST_Expression::EV_bool: + if (total_case_members == 2) + { + this->default_value_.computed_ = 0; + } + + break; + case AST_Expression::EV_enum: + // Has to be enum. + { + AST_Decl *d = AST_Decl::narrow_from_decl (this->disc_type ()); + + if (d->node_type () == AST_Decl::NT_typedef) + { + AST_Typedef *bt = AST_Typedef::narrow_from_decl (d); + d = bt->primitive_base_type (); + } + + AST_Enum *en = AST_Enum::narrow_from_decl (d); + + if (en != 0) + { + if (total_case_members == en->member_count ()) + { + this->default_value_.computed_ = 0; + } + } + else + { + // Error. + this->default_value_.computed_ = -1; + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%N:%l) AST_Union::") + ACE_TEXT ("compute_default_value ") + ACE_TEXT ("- disc type not an ENUM\n")), + -1); + } + } + break; + default: + // Error. + this->default_value_.computed_ = -1; + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%N:%l) AST_Union::compute_default_value") + ACE_TEXT (" - Bad discriminant type\n")), + -1); + ACE_NOTREACHED (break;) + } // End of switch + + // If we have determined that we don't have a default case and even then a + // default case was provided, flag this off as error. + if ((this->default_value_.computed_ == 0) + && (this->default_index () != -1)) + { + // Error. + this->default_value_.computed_ = -1; + ACE_ERROR_RETURN ((LM_ERROR, + ACE_TEXT ("(%N:%l) AST_Union::compute_default_value") + ACE_TEXT (" - default clause is invalid here\n")), + -1); + } + + // Proceed only if necessary. + switch (this->default_value_.computed_) + { + case -1: + // Error. We should never be here because errors + // have already been caught + // above. + return -1; + case 0: + // Nothing more to do. + return 0; + default: + // Proceed further down. + break; + } + + // Initialization of the default value data member. + switch (this->udisc_type ()) + { + case AST_Expression::EV_short: + this->default_value_.u.short_val = ACE_INT16_MIN; + break; + case AST_Expression::EV_ushort: + this->default_value_.u.ushort_val = 0; + break; + case AST_Expression::EV_long: + // The +1 is to avert a warning on many compilers. + this->default_value_.u.long_val = ACE_INT32_MIN + 1; + break; + case AST_Expression::EV_ulong: + this->default_value_.u.ulong_val = 0; + break; + case AST_Expression::EV_char: + this->default_value_.u.char_val = 0; + break; + case AST_Expression::EV_wchar: + this->default_value_.u.wchar_val = 0; + break; + case AST_Expression::EV_bool: + this->default_value_.u.bool_val = 0; + break; + case AST_Expression::EV_enum: + this->default_value_.u.enum_val = 0; + break; + case AST_Expression::EV_longlong: + case AST_Expression::EV_ulonglong: + // Unimplemented. + default: + // Error caught earlier. + break; + } + + // Proceed until we have found the appropriate default value. + while (this->default_value_.computed_ == -2) + { + int break_loop = 0; + + // Instantiate a scope iterator. + for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls); + !si.is_done () && break_loop == 0; + si.next ()) + { + // Get the next AST decl node + AST_UnionBranch *ub = + AST_UnionBranch::narrow_from_decl (si.item ()); + + if (ub != 0) + { + for (unsigned long i = 0; + i < ub->label_list_length () && !break_loop; + ++i) + { + if (ub->label (i)->label_kind () == AST_UnionLabel::UL_label) + { + // Not a default. + AST_Expression *expr = ub->label (i)->label_val (); + + if (expr == 0) + { + // Error. + this->default_value_.computed_ = -1; + ACE_ERROR_RETURN (( + LM_ERROR, + ACE_TEXT ("(%N:%l) AST_Union::") + ACE_TEXT ("compute_default_value - ") + ACE_TEXT ("Bad case label value\n") + ), + -1 + ); + } + + switch (expr->ev ()->et) + { + // Check if they match in which case this + // cannot be the implicit default value. So + // start with a new value and try the whole loop + // again because our case labels may not be sorted. + case AST_Expression::EV_short: + if (this->default_value_.u.short_val + == expr->ev ()->u.sval) + { + this->default_value_.u.short_val++; + break_loop = 1; + } + + break; + case AST_Expression::EV_ushort: + if (this->default_value_.u.ushort_val + == expr->ev ()->u.usval) + { + this->default_value_.u.ushort_val++; + break_loop = 1; + } + + break; + case AST_Expression::EV_long: + if (this->default_value_.u.long_val + == expr->ev ()->u.lval) + { + this->default_value_.u.long_val++; + break_loop = 1; + } + + break; + case AST_Expression::EV_ulong: + if (this->default_value_.u.ulong_val + == expr->ev ()->u.ulval) + { + this->default_value_.u.ulong_val++; + break_loop = 1; + } + + break; + case AST_Expression::EV_char: + if (this->default_value_.u.char_val + == expr->ev ()->u.cval) + { + this->default_value_.u.char_val++; + break_loop = 1; + } + + break; + case AST_Expression::EV_wchar: + if (this->default_value_.u.wchar_val + == expr->ev ()->u.wcval) + { + this->default_value_.u.wchar_val++; + break_loop = 1; + } + + break; + case AST_Expression::EV_bool: + if (this->default_value_.u.bool_val + == expr->ev ()->u.bval) + { + this->default_value_.u.bool_val ^= true; + break_loop = 1; + } + + break; + case AST_Expression::EV_enum: + // this is the case of enums. We maintain + // evaluated values which always start with 0 + if (this->default_value_.u.enum_val + == expr->ev ()->u.eval) + { + this->default_value_.u.enum_val++; + break_loop = 1; + } + + break; + case AST_Expression::EV_longlong: + case AST_Expression::EV_ulonglong: + // Unimplemented. right now - flag as error. + default: + // Error. + break; + } // End of switch. + } // if label_Kind == label + } // End of for loop going thru all labels. + } // If valid union branch. + } // End of while scope iterator loop. + + // We have not aborted the inner loops which means we have found the + // default value. + if (break_loop == 0) + { + this->default_value_.computed_ = 1; + } + + } // End of outer while (default_value.computed == -2). + + return 0; +} + +// Private operations. + +// Compute the default index. +int +AST_Union::compute_default_index (void) +{ + AST_Decl *d = 0; + AST_UnionBranch *ub = 0; + int i = 0; + + // If default case does not exist, it will have a value of -1 according to + // the spec. + this->default_index_ = -1; + + // If there are elements in this scope... + if (this->nmembers () > 0) + { + // Instantiate a scope iterator. + for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + // Get the next AST decl node. + d = si.item (); + + // If an enum is declared in our scope, its members are + // added to our scope as well, to detect clashes. + if (d->node_type () == AST_Decl::NT_enum_val) + { + continue; + } + + if (!d->imported ()) + { + ub = AST_UnionBranch::narrow_from_decl (d); + + for (unsigned long j = 0; j < ub->label_list_length (); ++j) + { + // Check if we are printing the default case. + AST_UnionLabel::UnionLabel ulk = ub->label ()->label_kind (); + if (ulk == AST_UnionLabel::UL_default) + { + // Zero based indexing. + this->default_index_ = i; + } + } + + // TAO's Typecode class keeps only a member count (not + // a label count) so this increment has been moved + // out of the inner loop. + ++i; + } + } + } + + return 0; +} + +// Redefinition of inherited virtual operations + +// Add this AST_UnionBranch node (a node representing one branch in a +// union declaration) to this scope +AST_UnionBranch * +AST_Union::fe_add_union_branch (AST_UnionBranch *t) +{ + AST_Decl *d = 0; + + // If this is a malformed branch, don't do anything with it. + if (t == 0 || t->label() == 0) + { + return 0; + } + + // If branch with that label already exists, complain. + if (lookup_branch (t) != 0) + { + idl_global->err ()->error2 (UTL_Error::EIDL_MULTIPLE_BRANCH, + this, + t); + return 0; + } + + // If branch with same field name exists, complain. + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // If we have an enum discriminator, add the label names to + // the name_referenced list before we add the union branch, + // so a branch name clash with a label name will be caught. + if (this->pd_udisc_type == AST_Expression::EV_enum) + { + t->add_labels (this); + } + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + AST_Type *ft = t->field_type (); + UTL_ScopedName *mru = ft->last_referenced_as (); + + if (mru != 0) + { + this->add_to_referenced (ft, + false, + mru->first_component ()); + } + + this->fields_.enqueue_tail (t); + + return t; +} + +// Add this AST_Union (manifest union type) to this scope. +AST_Union * +AST_Union::fe_add_union (AST_Union *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to local types. + this->add_to_local_types (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_Structure node (manifest struct type) to this scope. +AST_Structure * +AST_Union::fe_add_structure (AST_Structure *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to local types. + this->add_to_local_types (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_Enum node (manifest enum type) to this scope. +AST_Enum * +AST_Union::fe_add_enum (AST_Enum *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to local types. + this->add_to_local_types (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Add this AST_EnumVal node (enumerator declaration) to this scope. +// This is done to conform to the C++ scoping rules which declare +// enumerators in the enclosing scope (in addition to declaring them +// in the enum itself). +AST_EnumVal * +AST_Union::fe_add_enum_val (AST_EnumVal *t) +{ + AST_Decl *d = 0; + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (t, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + t, + this, + d); + return 0; + } + + if (this->referenced (d, t->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + t, + this, + d); + return 0; + } + + if (t->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (t, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (t); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (t, + false, + t->local_name ()); + + return t; +} + +// Dump this AST_Union node to the ostream o. +void +AST_Union::dump (ACE_OSTREAM_TYPE &o) +{ + o << "union "; + this->local_name ()->dump (o); + o << " switch ("; + this->pd_disc_type->local_name ()->dump (o); + o << ") {\n"; + UTL_Scope::dump (o); + idl_global->indent ()->skip_to (o); + o << "}"; +} + +// Compute the size type of the node in question. +int +AST_Union::compute_size_type (void) +{ + for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls); + !si.is_done (); + si.next ()) + { + // Get the next AST decl node. + AST_Decl *d = si.item (); + + if (d->node_type () == AST_Decl::NT_enum_val) + { + continue; + } + + AST_Field *f = AST_Field::narrow_from_decl (d); + + if (f != 0) + { + AST_Type *t = f->field_type (); + // Our sizetype depends on the sizetype of our members. Although + // previous value of sizetype may get overwritten, we are + // guaranteed by the "size_type" call that once the value reached + // be_decl::VARIABLE, nothing else can overwrite it. + this->size_type (t->size_type ()); + } + else + { + ACE_DEBUG ((LM_DEBUG, + "WARNING (%N:%l) be_union::compute_size_type - " + "narrow_from_decl returned 0\n")); + } + } + + return 0; +} + +int +AST_Union::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_union (this); +} + +// Data accessors. + +AST_ConcreteType * +AST_Union::disc_type (void) +{ + return this->pd_disc_type; +} + +AST_Expression::ExprType +AST_Union::udisc_type (void) +{ + return this->pd_udisc_type; +} + +// Narrowing. +IMPL_NARROW_METHODS1(AST_Union, AST_Structure) +IMPL_NARROW_FROM_DECL(AST_Union) +IMPL_NARROW_FROM_SCOPE(AST_Union) diff --git a/TAO/TAO_IDL/ast/ast_union_branch.cpp b/TAO/TAO_IDL/ast/ast_union_branch.cpp new file mode 100644 index 00000000000..8fff20afb86 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_union_branch.cpp @@ -0,0 +1,199 @@ +// $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. + +*/ + +// AST_UnionBranch nodes represent a single branch of an IDL union +// declaration. +// AST_UnionBranch is a subclass of AST_Field, adding a label (which +// is a subclass of AST_UnionLabel). + +#include "ast_union_branch.h" +#include "ast_union_label.h" +#include "ast_union.h" +#include "ast_visitor.h" +#include "utl_labellist.h" + +ACE_RCSID(ast, ast_union_branch, "$Id$") + +AST_UnionBranch::AST_UnionBranch (void) + : COMMON_Base (), + AST_Decl (), + AST_Field (), + pd_ll (0) +{ +} + +AST_UnionBranch::AST_UnionBranch (UTL_LabelList *ll, + AST_Type *ft, + UTL_ScopedName *n) + : COMMON_Base (), + AST_Decl (AST_Decl::NT_union_branch, + n), + AST_Field (AST_Decl::NT_union_branch, + ft, + n), + pd_ll (ll) +{ +} + +AST_UnionBranch::~AST_UnionBranch (void) +{ +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_UnionBranch node to the ostream o. +void +AST_UnionBranch::dump (ACE_OSTREAM_TYPE &o) +{ + for (unsigned long i = 0; i < this->label_list_length (); ++i) + { + this->dump_i (o, "case "); + + AST_UnionLabel *ul = this->label (i); + ul->dump (o); + + this->dump_i (o, ": \n"); + } + + AST_Field::dump (o); +} + +int +AST_UnionBranch::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_union_branch (this); +} + +void +AST_UnionBranch::destroy (void) +{ + this->pd_ll->destroy (); + delete this->pd_ll; + this->pd_ll = 0; + + this->AST_Field::destroy (); +} + +// Data accessors. + +AST_UnionLabel * +AST_UnionBranch::label (unsigned long index) +{ + unsigned long i = 0; + + for (UTL_LabellistActiveIterator iter (this->pd_ll); + !iter.is_done (); + iter.next ()) + { + if (i == index) + { + return iter.item (); + } + + ++i; + } + + return 0; +} + +unsigned long +AST_UnionBranch::label_list_length (void) +{ + if (this->pd_ll) + { + return this->pd_ll->length (); + } + else + { + return 0; + } +} + +void +AST_UnionBranch::add_labels (AST_Union *u) +{ + AST_UnionLabel *ul = 0; + AST_Expression *ex = 0; + + for (UTL_LabellistActiveIterator i (this->pd_ll); + !i.is_done (); + i.next ()) + { + ul = i.item (); + + if (ul->label_kind () == AST_UnionLabel::UL_default) + { + return; + } + + ex = ul->label_val (); + u->add_to_name_referenced (ex->n ()->first_component ()); + } +} + +// Narrowing. +IMPL_NARROW_METHODS1(AST_UnionBranch, AST_Field) +IMPL_NARROW_FROM_DECL(AST_UnionBranch) diff --git a/TAO/TAO_IDL/ast/ast_union_fwd.cpp b/TAO/TAO_IDL/ast/ast_union_fwd.cpp new file mode 100644 index 00000000000..b1549dc0c16 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_union_fwd.cpp @@ -0,0 +1,65 @@ +// $Id$ + +// AST_UnionFwd nodes denote forward declarations of IDL union. +// AST_UnionFwd nodes have a field containing the full declaration +// of the union, which is initialized when that declaration is +// encountered. + +#include "ast_union_fwd.h" +#include "ast_union.h" +#include "ast_visitor.h" +#include "utl_identifier.h" + +ACE_RCSID (ast, + ast_union_fwd, + "$Id$") + +AST_UnionFwd::AST_UnionFwd (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + AST_StructureFwd () +{ +} + +AST_UnionFwd::AST_UnionFwd (AST_Union *dummy, + UTL_ScopedName *n) + : COMMON_Base (), + AST_Decl (AST_Decl::NT_union_fwd, + n), + AST_Type (AST_Decl::NT_union_fwd, + n), + AST_StructureFwd (dummy, + n) +{ +} + +AST_UnionFwd::~AST_UnionFwd (void) +{ +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_StructureFwd node to the ostream o. +void +AST_UnionFwd::dump (ACE_OSTREAM_TYPE &o) +{ + this->dump_i (o, "union "); + this->local_name ()->dump (o); +} + +int +AST_UnionFwd::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_union_fwd (this); +} + +void +AST_UnionFwd::destroy (void) +{ + this->AST_StructureFwd::destroy (); +} + +// Narrowing methods. +IMPL_NARROW_METHODS1 (AST_UnionFwd, AST_StructureFwd) +IMPL_NARROW_FROM_DECL (AST_UnionFwd) diff --git a/TAO/TAO_IDL/ast/ast_union_label.cpp b/TAO/TAO_IDL/ast/ast_union_label.cpp new file mode 100644 index 00000000000..37a2e337020 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_union_label.cpp @@ -0,0 +1,150 @@ +// $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. + +*/ +// AST_UnionLabel denotes the label of a branch in an IDL union +// declaration. +// AST_UnionLabel nodes have a label kind (the values come from the +// enum AST_UnionLabel::LabelKind) and a label value (which is a +// subclass of AST_Expression). + +#include "ast_union_label.h" +#include "ast_expression.h" +#include "ast_visitor.h" + +// FUZZ: disable check_for_streams_include +#include "ace/streams.h" + +ACE_RCSID (ast, + ast_union_label, + "$Id$") + +AST_UnionLabel::AST_UnionLabel (void) + : pd_label_kind (UL_default), + pd_label_val (0) +{ +} + +AST_UnionLabel::AST_UnionLabel (UnionLabel lk, + AST_Expression *lv) + : pd_label_kind (lk), + pd_label_val (lv) +{ + if (lv != 0) + { + lv->evaluate (AST_Expression::EK_const); + } +} + +AST_UnionLabel::~AST_UnionLabel (void) +{ +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_UnionLabel node to the ostream o. +void +AST_UnionLabel::dump (ACE_OSTREAM_TYPE &o) +{ + if (this->pd_label_kind == UL_default) + { + o << "default"; + } + else + { + this->pd_label_val->dump (o); + } +} + +int +AST_UnionLabel::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_union_label (this); +} + +void +AST_UnionLabel::destroy (void) +{ + // Otherwise (default label) our label value is 0. + if (UL_label == this->pd_label_kind) + { + this->pd_label_val->destroy (); + delete this->pd_label_val; + this->pd_label_val = 0; + } +} + +// Data accessors. + +AST_UnionLabel::UnionLabel +AST_UnionLabel::label_kind (void) +{ + return this->pd_label_kind; +} + +AST_Expression * +AST_UnionLabel::label_val (void) +{ + return this->pd_label_val; +} diff --git a/TAO/TAO_IDL/ast/ast_valuebox.cpp b/TAO/TAO_IDL/ast/ast_valuebox.cpp new file mode 100644 index 00000000000..0b687de22dc --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_valuebox.cpp @@ -0,0 +1,68 @@ +// $Id$ + +#include "ast_valuebox.h" +#include "ast_visitor.h" +#include "utl_identifier.h" + +ACE_RCSID (ast, + ast_valuebox, + "ast_valuebox.cpp,v 1.0 Exp") + +AST_ValueBox::AST_ValueBox (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + AST_ConcreteType () +{ +} + +AST_ValueBox::AST_ValueBox (UTL_ScopedName *n, + AST_Type *boxed_type) + : COMMON_Base (), + AST_Decl (AST_Decl::NT_valuebox, + n, true), + AST_Type (AST_Decl::NT_valuebox, + n), + AST_ConcreteType (AST_Decl::NT_valuebox, n), + pd_boxed_type (boxed_type) +{ +} + +AST_ValueBox::~AST_ValueBox (void) +{ +} + +AST_Type * +AST_ValueBox::boxed_type (void) const +{ + return this->pd_boxed_type; +} + +void +AST_ValueBox::dump (ACE_OSTREAM_TYPE &o) +{ + + this->dump_i (o, "valuetype "); + + this->local_name ()->dump (o); + this->dump_i (o, " "); + this->pd_boxed_type->dump (o); +} + +int +AST_ValueBox::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_valuebox (this); +} + +void +AST_ValueBox::destroy (void) +{ + this->AST_ConcreteType::destroy (); +} + +// Narrowing. +IMPL_NARROW_METHODS1(AST_ValueBox, AST_ConcreteType) +IMPL_NARROW_FROM_DECL(AST_ValueBox) + + diff --git a/TAO/TAO_IDL/ast/ast_valuetype.cpp b/TAO/TAO_IDL/ast/ast_valuetype.cpp new file mode 100644 index 00000000000..459525d98b3 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_valuetype.cpp @@ -0,0 +1,473 @@ +// This may look like C, but it's really -*- C++ -*- +// $Id$ + +#include "ast_valuetype.h" +#include "ast_factory.h" +#include "ast_visitor.h" +#include "ast_extern.h" +#include "ast_field.h" +#include "utl_err.h" +#include "utl_identifier.h" +#include "utl_indenter.h" +#include "utl_string.h" +#include "global_extern.h" +#include "nr_extern.h" + +#include "ace/streams.h" + +ACE_RCSID (ast, + ast_valuetype, + "$Id$") + +AST_ValueType::AST_ValueType (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + UTL_Scope (), + AST_Interface (), + pd_supports (0), + pd_n_supports (0), + pd_inherits_concrete (0), + pd_supports_concrete (0), + pd_truncatable (false), + pd_custom (false) +{ +} + +AST_ValueType::AST_ValueType (UTL_ScopedName *n, + AST_Interface **inherits, + long n_inherits, + AST_ValueType *inherits_concrete, + AST_Interface **inherits_flat, + long n_inherits_flat, + AST_Interface **supports, + long n_supports, + AST_Interface *supports_concrete, + bool abstract, + bool truncatable, + bool custom) + : COMMON_Base (false, + abstract), + AST_Decl (AST_Decl::NT_valuetype, + n), + AST_Type (AST_Decl::NT_valuetype, + n), + UTL_Scope (AST_Decl::NT_valuetype), + AST_Interface (n, + inherits, + n_inherits, + inherits_flat, + n_inherits_flat, + false, + abstract), + pd_supports (supports), + pd_n_supports (n_supports), + pd_inherits_concrete (inherits_concrete), + pd_supports_concrete (supports_concrete), + pd_truncatable (truncatable), + pd_custom (custom) +{ +} + +AST_ValueType::~AST_ValueType (void) +{ +} + +void +AST_ValueType::redefine (AST_Interface *from) +{ + AST_ValueType *vt = AST_ValueType::narrow_from_decl (from); + + if (vt == 0) + { + idl_global->err ()->redef_error (from->local_name ()->get_string (), + this->local_name ()->get_string ()); + return; + } + + // Copy over all the base class members. + this->AST_Interface::redefine (from); + + this->pd_inherits_concrete = vt->pd_inherits_concrete; + this->pd_supports_concrete = vt->pd_supports_concrete; + this->pd_truncatable = vt->pd_truncatable; +} + +AST_Interface ** +AST_ValueType::supports (void) const +{ + return this->pd_supports; +} + +long +AST_ValueType::n_supports (void) const +{ + return this->pd_n_supports; +} + +AST_ValueType * +AST_ValueType::inherits_concrete (void) const +{ + return this->pd_inherits_concrete; +} + +AST_Interface * +AST_ValueType::supports_concrete (void) const +{ + return this->pd_supports_concrete; +} + +bool +AST_ValueType::truncatable (void) const +{ + return this->pd_truncatable; +} + +bool +AST_ValueType::custom (void) const +{ + return this->pd_custom; +} + +bool +AST_ValueType::will_have_factory (void) +{ + return false; +} + +// Look through supported interface list. +AST_Decl * +AST_ValueType::look_in_supported (UTL_ScopedName *e, + bool treat_as_ref) +{ + AST_Decl *d = 0; + AST_Decl *d_before = 0; + AST_Interface **is = 0; + long nis = -1; + + // Can't look in an interface which was not yet defined. + if (!this->is_defined ()) + { +// idl_global->err ()->fwd_decl_lookup (this, +// e); + return 0; + } + + // OK, loop through supported interfaces. + + // (Don't leave the inheritance hierarchy, no module or global ...) + // Find all and report ambiguous results as error. + + for (nis = this->n_supports (), is = this->supports (); + nis > 0; + nis--, is++) + { + d = (*is)->lookup_by_name (e, + treat_as_ref, + 0 /* not in parent */); + if (d != 0) + { + if (d_before == 0) + { + // First result found. + d_before = d; + } + else + { + // Conflict against further results? + if (d != d_before) + { + ACE_ERROR ((LM_ERROR, + "warning in %s line %d: ", + idl_global->filename ()->get_string (), + idl_global->lineno ())); + + e->dump (*ACE_DEFAULT_LOG_STREAM); + + ACE_ERROR ((LM_ERROR, + " is ambiguous in scope.\n" + "Found ")); + + d->name ()->dump (*ACE_DEFAULT_LOG_STREAM); + + ACE_ERROR ((LM_ERROR, + " and ")); + + d_before->name ()->dump (*ACE_DEFAULT_LOG_STREAM); + + ACE_ERROR ((LM_ERROR, + ".\n")); + } + } + } + } + + return d_before; +} + +bool +AST_ValueType::legal_for_primary_key (void) const +{ + AST_ValueType *pk_base = this->lookup_primary_key_base (); + + if (!this->derived_from_primary_key_base (this, pk_base)) + { + return false; + } + + bool has_public_member = false; + bool retval = true; + + if (!this->recursing_in_legal_pk_) + { + this->recursing_in_legal_pk_ = true; + + for (UTL_ScopeActiveIterator i (const_cast<AST_ValueType *> (this), + UTL_Scope::IK_decls); + !i.is_done (); + i.next ()) + { + AST_Field *f = AST_Field::narrow_from_decl (i.item ()); + + // We're not interested in any valuetype decls that aren't fields. + if (f == 0) + { + continue; + } + + // Private members are not allowed in primary keys. + if (f->visibility () == AST_Field::vis_PRIVATE) + { + retval = false; + break; + } + else + { + // Returns false for interfaces, components, homes. + // Called recursively on valuetypes and on members of + // structs, unions, sequences, typedefs and arrays. Returns + // TRUE otherwise. + if (!f->field_type ()->legal_for_primary_key ()) + { + retval = false; + break; + } + + has_public_member = true; + } + } + + this->recursing_in_legal_pk_ = false; + } + + // Must have at least one public member, unless we are + // short-circuiting the test because we are in recursion. + return retval && (has_public_member || this->recursing_in_legal_pk_); +} + +void +AST_ValueType::destroy (void) +{ + delete [] this->pd_supports; + this->pd_supports = 0; + this->pd_n_supports = 0; + + this->AST_Interface::destroy (); +} + +void +AST_ValueType::dump (ACE_OSTREAM_TYPE &o) +{ + if (this->is_abstract ()) + { + this->dump_i (o, "abstract "); + } + else if (this->pd_truncatable) + { + this->dump_i (o, "truncatable "); + } + + this->dump_i (o, "valuetype "); + + this->local_name ()->dump (o); + this->dump_i (o, " "); + + if (this->pd_n_inherits > 0) + { + this->dump_i (o, ": "); + + for (long i = 0; i < this->pd_n_inherits; ++i) + { + this->pd_inherits[i]->local_name ()->dump (o); + + if (i < this->pd_n_inherits - 1) + { + this->dump_i (o, ", "); + } + } + } + + this->dump_i (o, "\n\n"); + + if (this->pd_n_supports > 0) + { + this->dump_i (o, "supports "); + + for (long i = 0; i < this->pd_n_supports; ++i) + { + this->pd_supports[i]->local_name ()->dump (o); + + if (i < this->pd_n_supports - 1) + { + this->dump_i (o, ", "); + } + } + } + + this->dump_i (o, " {\n"); + + UTL_Scope::dump (o); + idl_global->indent ()->skip_to (o); + + this->dump_i (o, "}"); +} + +int +AST_ValueType::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_valuetype (this); +} + +AST_Factory * +AST_ValueType::fe_add_factory (AST_Factory *f) +{ + AST_Decl *d = 0; + + // Can't add to interface which was not yet defined. + if (!this->is_defined ()) + { + idl_global->err ()->error2 (UTL_Error::EIDL_DECL_NOT_DEFINED, + this, + f); + return 0; + } + + // Already defined and cannot be redefined? Or already used? + if ((d = this->lookup_for_add (f, false)) != 0) + { + if (!can_be_redefined (d)) + { + idl_global->err ()->error3 (UTL_Error::EIDL_REDEF, + f, + this, + d); + return 0; + } + + if (this->referenced (d, f->local_name ())) + { + idl_global->err ()->error3 (UTL_Error::EIDL_DEF_USE, + f, + this, + d); + return 0; + } + + if (f->has_ancestor (d)) + { + idl_global->err ()->redefinition_in_scope (f, + d); + return 0; + } + } + + // Add it to scope. + this->add_to_scope (f); + + // Add it to set of locally referenced symbols. + this->add_to_referenced (f, + false, + f->local_name ()); + + return f; +} + +bool +AST_ValueType::derived_from_primary_key_base (const AST_ValueType *node, + const AST_ValueType *pk_base) const +{ + if (0 == node) + { + return false; + } + + if (node == pk_base) + { + return true; + } + + AST_ValueType *concrete_parent = node->inherits_concrete (); + + if (this->derived_from_primary_key_base (concrete_parent, pk_base)) + { + return true; + } + + AST_Interface **v = node->pd_inherits; + + for (long i = 0; i < node->pd_n_inherits; ++i) + { + AST_ValueType *tmp = AST_ValueType::narrow_from_decl (v[i]); + + if (this->derived_from_primary_key_base (tmp, pk_base)) + { + return true; + } + } + + return false; +} + +AST_ValueType * +AST_ValueType::lookup_primary_key_base (void) const +{ + AST_ValueType *retval = idl_global->primary_key_base (); + + if (retval == 0) + { + Identifier local_id ("PrimaryKeyBase"); + UTL_ScopedName local_name (&local_id, 0); + + Identifier scope_name ("Components"); + UTL_ScopedName pk_name (&scope_name, &local_name); + AST_Decl *d = + const_cast<AST_ValueType *> (this)->lookup_by_name (&pk_name, true); + + local_id.destroy (); + scope_name.destroy (); + + if (d == 0) + { + idl_global->err ()->lookup_error (&pk_name); + return 0; + } + + retval = AST_ValueType::narrow_from_decl (d); + + if (retval == 0) + { + idl_global->err ()->valuetype_expected (d); + return 0; + } + + idl_global->primary_key_base (retval); + } + + return retval; +} + +// Narrowing. +IMPL_NARROW_METHODS1(AST_ValueType, AST_Interface) +IMPL_NARROW_FROM_DECL(AST_ValueType) +IMPL_NARROW_FROM_SCOPE(AST_ValueType) + diff --git a/TAO/TAO_IDL/ast/ast_valuetype_fwd.cpp b/TAO/TAO_IDL/ast/ast_valuetype_fwd.cpp new file mode 100644 index 00000000000..8f436fbcd21 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_valuetype_fwd.cpp @@ -0,0 +1,66 @@ +// $Id$ + +#include "ast_valuetype_fwd.h" +#include "ast_interface.h" +#include "ast_visitor.h" +#include "utl_identifier.h" + +ACE_RCSID( ast, + ast_valuetype_fwd, + "$Id$") + +AST_ValueTypeFwd::AST_ValueTypeFwd (void) + : COMMON_Base (), + AST_Decl (), + AST_Type (), + AST_InterfaceFwd () +{ +} + +AST_ValueTypeFwd::AST_ValueTypeFwd (AST_Interface *dummy, + UTL_ScopedName *n) + : COMMON_Base (false, + dummy->is_abstract ()), + AST_Decl (AST_Decl::NT_valuetype_fwd, + n), + AST_Type (AST_Decl::NT_valuetype_fwd, + n), + AST_InterfaceFwd (dummy, + n) +{ +} + +AST_ValueTypeFwd::~AST_ValueTypeFwd (void) +{ +} + +// Redefinition of inherited virtual operations. + +// Dump this AST_InterfaceFwd node to the ostream o. +void +AST_ValueTypeFwd::dump (ACE_OSTREAM_TYPE &o) +{ + if (this->is_abstract ()) + { + this->dump_i (o, "abstract "); + } + + this->dump_i (o, "valuetype "); + + this->local_name ()->dump (o); +} + +int +AST_ValueTypeFwd::ast_accept (ast_visitor *visitor) +{ + return visitor->visit_valuetype_fwd (this); +} + +void +AST_ValueTypeFwd::destroy (void) +{ +} + +// Narrowing methods. +IMPL_NARROW_METHODS1 (AST_ValueTypeFwd, AST_InterfaceFwd) +IMPL_NARROW_FROM_DECL (AST_ValueTypeFwd) diff --git a/TAO/TAO_IDL/ast/ast_visitor.cpp b/TAO/TAO_IDL/ast/ast_visitor.cpp new file mode 100644 index 00000000000..35c8f8566f6 --- /dev/null +++ b/TAO/TAO_IDL/ast/ast_visitor.cpp @@ -0,0 +1,16 @@ +// $Id$ + +#include "ast_visitor.h" +#include "ace/config-all.h" + +ACE_RCSID (ast, + ast_visitor, + "$Id$") + +ast_visitor::ast_visitor (void) +{ +} + +ast_visitor::~ast_visitor (void) +{ +} |