diff options
Diffstat (limited to 'TAO/TAO_IDL/be/be_union.cpp')
-rw-r--r-- | TAO/TAO_IDL/be/be_union.cpp | 1045 |
1 files changed, 0 insertions, 1045 deletions
diff --git a/TAO/TAO_IDL/be/be_union.cpp b/TAO/TAO_IDL/be/be_union.cpp deleted file mode 100644 index 4aa4baa22fe..00000000000 --- a/TAO/TAO_IDL/be/be_union.cpp +++ /dev/null @@ -1,1045 +0,0 @@ -// $Id$ - -// ============================================================================ -// -// = LIBRARY -// TAO IDL -// -// = FILENAME -// be_union.cpp -// -// = DESCRIPTION -// Extension of class AST_Union that provides additional means for C++ -// mapping. -// -// = AUTHOR -// Copyright 1994-1995 by Sun Microsystems, Inc. -// and -// Aniruddha Gokhale -// -// ============================================================================ - -#include "idl.h" -#include "idl_extern.h" -#include "be.h" - -ACE_RCSID(be, be_union, "$Id$") - - -/* - * BE_Union - */ - -be_union::be_union (void) -{ -} - -be_union::be_union (AST_ConcreteType *dt, UTL_ScopedName *n, UTL_StrList *p) - : AST_Union (dt, n, p), - AST_Structure (AST_Decl::NT_union, n, p), - AST_Decl (AST_Decl::NT_union, n, p), - UTL_Scope (AST_Decl::NT_union), - member_count_ (-1), - default_index_ (-2) -{ - this->default_value_.computed_ = -2; -} - -// compute total number of members -int -be_union::compute_member_count (void) -{ - UTL_ScopeActiveIterator *si; // iterator - - this->member_count_ = 0; - - // if there are elements in this scope - if (this->nmembers () > 0) - { - // instantiate a scope iterator. - si = new UTL_ScopeActiveIterator (this, UTL_Scope::IK_decls); - - while (!(si->is_done ())) - { - this->member_count_++; - si->next (); - } // end of while - delete si; // free the iterator object - } - return 0; -} - -// compute total number of members -int -be_union::compute_default_index (void) -{ - UTL_ScopeActiveIterator *si; // iterator - AST_Decl *d; // temp node - be_union_branch *bub; // union branch node - int i = 0; // counter - - // 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. - si = new UTL_ScopeActiveIterator (this, UTL_Scope::IK_decls); - - while (!(si->is_done ())) - { - // get the next AST decl node - d = si->item (); - if (!d->imported ()) - { - bub = be_union_branch::narrow_from_decl (d); - for (unsigned long j = 0; - j < bub->label_list_length (); - ++j) - { - // check if we are printing the default case - if (bub->label (j)->label_kind () - == AST_UnionLabel::UL_default) - this->default_index_ = i; // zero based indexing - i++; - } - } - si->next (); - } // end of while - delete si; // free the iterator object - } - return 0; -} - -// return the member count -int -be_union::member_count (void) -{ - if (this->member_count_ == -1) - this->compute_member_count (); - - return this->member_count_; -} - -// return the default_index -int -be_union::default_index (void) -{ - if (this->default_index_ == -2) - this->compute_default_index (); - - return this->default_index_; -} - -// generate the _var definition for ourself -int -be_union::gen_var_defn (char *) -{ - TAO_OutStream *ch; // output stream - TAO_NL nl; // end line - char namebuf [NAMEBUFSIZE]; // names - - ACE_OS::memset (namebuf, '\0', NAMEBUFSIZE); - ACE_OS::sprintf (namebuf, "%s_var", this->local_name ()->get_string ()); - - // retrieve a singleton instance of the code generator - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - - ch = cg->client_header (); - - // generate the var definition (always in the client header). - // Depending upon the data type, there are some differences which we account - // for over here. - - ch->indent (); // start with whatever was our current indent level - *ch << "class " << idl_global->export_macro () - << " " << namebuf << nl; - *ch << "{" << nl; - *ch << "public:\n"; - ch->incr_indent (); - // default constr - *ch << namebuf << " (void); // default constructor" << nl; - // constr - *ch << namebuf << " (" << local_name () << " *);" << nl; - // copy constructor - *ch << namebuf << " (const " << namebuf << - " &); // copy constructor" << nl; - // destructor - *ch << "~" << namebuf << " (void); // destructor" << nl; - *ch << nl; - // assignment operator from a pointer - *ch << namebuf << " &operator= (" << local_name () << " *);" << nl; - // assignment from _var - *ch << namebuf << " &operator= (const " << namebuf << " &);" << nl; - - // arrow operator - *ch << local_name () << " *operator-> (void);" << nl; - *ch << "const " << local_name () << " *operator-> (void) const;" << nl; - *ch << nl; - - // other extra types (cast operators, [] operator, and others) - *ch << "operator const " << local_name () << " &() const;" << nl; - *ch << "operator " << local_name () << " &();" << nl; - *ch << "operator " << local_name () << " &() const;" << nl; - *ch << "// in, inout, out, _retn " << nl; - // the return types of in, out, inout, and _retn are based on the parameter - // passing rules and the base type - if (this->size_type () == be_decl::FIXED) - { - *ch << "const " << local_name () << " &in (void) const;" << nl; - *ch << local_name () << " &inout (void);" << nl; - *ch << local_name () << " &out (void);" << nl; - *ch << local_name () << " _retn (void);" << nl; - } - else - { - *ch << "const " << local_name () << " &in (void) const;" << nl; - *ch << local_name () << " &inout (void);" << nl; - *ch << local_name () << " *&out (void);" << nl; - *ch << local_name () << " *_retn (void);" << nl; - } - - // generate an additional member function that returns the underlying pointer - *ch << local_name () << " *ptr(void) const;\n"; - - *ch << "\n"; - ch->decr_indent (); - - // generate the private section - *ch << "private:\n"; - ch->incr_indent (); - *ch << local_name () << " *ptr_;\n"; - ch->decr_indent (); - *ch << "};\n\n"; - - return 0; -} - -// implementation of the _var class. All of these get generated in the inline -// file -int -be_union::gen_var_impl (char *, char *) -{ - TAO_OutStream *ci; // output stream - TAO_NL nl; // end line - char fname [NAMEBUFSIZE]; // to hold the full and - char lname [NAMEBUFSIZE]; // local _var names - - ACE_OS::memset (fname, '\0', NAMEBUFSIZE); - ACE_OS::sprintf (fname, "%s_var", this->fullname ()); - - ACE_OS::memset (lname, '\0', NAMEBUFSIZE); - ACE_OS::sprintf (lname, "%s_var", local_name ()->get_string ()); - - // retrieve a singleton instance of the code generator - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - - ci = cg->client_inline (); - - ci->indent (); // start with whatever was our current indent level - - *ci << "// *************************************************************" - << nl; - *ci << "// Inline operations for class " << fname << nl; - *ci << "// *************************************************************\n\n"; - - // default constr - *ci << "ACE_INLINE" << nl; - *ci << fname << "::" << lname << - " (void) // default constructor" << nl; - *ci << " " << ": ptr_ (0)" << nl; - *ci << "{}\n\n"; - - // constr from a pointer - ci->indent (); - *ci << "ACE_INLINE" << nl; - *ci << fname << "::" << lname << " (" << name () << " *p)" << nl; - *ci << " : ptr_ (p)" << nl; - *ci << "{}\n\n"; - - // copy constructor - ci->indent (); - *ci << "ACE_INLINE" << nl; - *ci << fname << "::" << lname << " (const " << fname << - " &p) // copy constructor" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "if (p.ptr_)" << nl; - *ci << " this->ptr_ = new " << this->name () << "(*p.ptr_);" << nl; - *ci << "else" << nl; - *ci << " this->ptr_ = 0;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - // destructor - ci->indent (); - *ci << "ACE_INLINE" << nl; - *ci << fname << "::~" << lname << " (void) // destructor" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "delete this->ptr_;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - // assignment operator from a pointer - ci->indent (); - *ci << "ACE_INLINE " << fname << " &" << nl; - *ci << fname << "::operator= (" << name () << - " *p)" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "delete this->ptr_;" << nl; - *ci << "this->ptr_ = p;" << nl; - *ci << "return *this;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - // assignment operator from _var - ci->indent (); - *ci << "ACE_INLINE " << fname << " &" << nl; - *ci << fname << "::operator= (const " << fname << - " &p)" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "if (this != &p)" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "delete this->ptr_;" << nl; - *ci << "this->ptr_ = new " << this->name () << " (*p.ptr_);\n"; - ci->decr_indent (); - *ci << "}" << nl; - *ci << "return *this;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - // two arrow operators - ci->indent (); - *ci << "ACE_INLINE const " << this->name () << " *" << nl; - *ci << fname << "::operator-> (void) const" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "return this->ptr_;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - ci->indent (); - *ci << "ACE_INLINE " << this->name () << " *" << nl; - *ci << fname << "::operator-> (void)" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "return this->ptr_;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - // other extra methods - 3 cast operator () - ci->indent (); - *ci << "ACE_INLINE " << nl; - *ci << fname << "::operator const " << name () << - " &() const // cast" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "return *this->ptr_;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - ci->indent (); - *ci << "ACE_INLINE " << nl; - *ci << fname << "::operator " << name () << " &() // cast " << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "return *this->ptr_;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - ci->indent (); - *ci << "ACE_INLINE " << nl; - *ci << fname << "::operator " << name () << " &() const// cast " << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "return *this->ptr_;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - // in, inout, out, and _retn - ci->indent (); - *ci << "ACE_INLINE const " << name () << " &" << nl; - *ci << fname << "::in (void) const" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "return *this->ptr_;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - ci->indent (); - *ci << "ACE_INLINE " << name () << " &" << nl; - *ci << fname << "::inout (void)" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "return *this->ptr_;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - // the out is handled differently based on our size type - ci->indent (); - if (this->size_type () == be_decl::VARIABLE) - { - *ci << "// mapping for variable size " << nl; - *ci << "ACE_INLINE " << name () << " *&" << nl; - *ci << fname << "::out (void)" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "delete this->ptr_;" << nl; - *ci << "this->ptr_ = 0;" << nl; - *ci << "return this->ptr_;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - ci->indent (); - *ci << "ACE_INLINE " << name () << " *" << nl; - *ci << fname << "::_retn (void)" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << this->name () << " *tmp = this->ptr_;" << nl; - *ci << "this->ptr_ = 0;" << nl; - *ci << "return tmp;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - } - else - { - *ci << "// mapping for fixed size " << nl; - *ci << "ACE_INLINE " << name () << " &" << nl; - *ci << fname << "::out (void)" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "return *this->ptr_;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - ci->indent (); - *ci << "ACE_INLINE " << name () << nl; - *ci << fname << "::_retn (void)" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "return *this->ptr_;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - // the additional ptr () member function - ci->indent (); - *ci << "ACE_INLINE " << name () << " *" << nl; - *ci << fname << "::ptr (void) const" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "return this->ptr_;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - } - - return 0; -} - -// generate the _out definition -int -be_union::gen_out_defn (char *) -{ - TAO_OutStream *ch; // output stream - TAO_NL nl; // end line - char namebuf [NAMEBUFSIZE]; // to hold the _out name - - ACE_OS::memset (namebuf, '\0', NAMEBUFSIZE); - ACE_OS::sprintf (namebuf, "%s_out", local_name ()->get_string ()); - - // retrieve a singleton instance of the code generator - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - - ch = cg->client_header (); - - // generate the out definition (always in the client header) - ch->indent (); // start with whatever was our current indent level - - *ch << "class " << idl_global->export_macro () - << " " << namebuf << nl; - *ch << "{" << nl; - *ch << "public:\n"; - ch->incr_indent (); - - // No default constructor - - // constructor from a pointer - *ch << namebuf << " (" << local_name () << " *&);" << nl; - // constructor from a _var & - *ch << namebuf << " (" << local_name () << "_var &);" << nl; - // constructor from a _out & - *ch << namebuf << " (const " << namebuf << " &);" << nl; - // assignment operator from a _out & - *ch << namebuf << " &operator= (const " << namebuf << " &);" << nl; - // assignment operator from a pointer &, cast operator, ptr fn, operator - // -> and any other extra operators - // assignment - *ch << namebuf << " &operator= (" << local_name () << " *);" << nl; - // operator () - *ch << "operator " << local_name () << " *&();" << nl; - // ptr fn - *ch << local_name () << " *&ptr (void);" << nl; - // operator -> - *ch << local_name () << " *operator-> (void);" << nl; - - *ch << "\n"; - ch->decr_indent (); - *ch << "private:\n"; - ch->incr_indent (); - *ch << local_name () << " *&ptr_;" << nl; - *ch << "// assignment from T_var not allowed" << nl; - *ch << "void operator= (const " << local_name () << "_var &);\n"; - - ch->decr_indent (); - *ch << "};\n\n"; - return 0; -} - -int -be_union::gen_out_impl (char *, char *) -{ - TAO_OutStream *ci; // output stream - TAO_NL nl; // end line - char fname [NAMEBUFSIZE]; // to hold the full and - char lname [NAMEBUFSIZE]; // local _out names - - ACE_OS::memset (fname, '\0', NAMEBUFSIZE); - ACE_OS::sprintf (fname, "%s_out", this->fullname ()); - - ACE_OS::memset (lname, '\0', NAMEBUFSIZE); - ACE_OS::sprintf (lname, "%s_out", local_name ()->get_string ()); - - // retrieve a singleton instance of the code generator - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - - ci = cg->client_inline (); - - // generate the var implementation in the inline file - - ci->indent (); // start with whatever was our current indent level - - *ci << "// *************************************************************" - << nl; - *ci << "// Inline operations for class " << fname << nl; - *ci << "// *************************************************************\n\n"; - - // constr from a pointer - ci->indent (); - *ci << "ACE_INLINE" << nl; - *ci << fname << "::" << lname << " (" << name () << " *&p)" << nl; - *ci << " : ptr_ (p)" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "this->ptr_ = 0;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - // constructor from _var & - ci->indent (); - *ci << "ACE_INLINE" << nl; - *ci << fname << "::" << lname << " (" << this->name () << - "_var &p) // constructor from _var" << nl; - *ci << " : ptr_ (p.out ())" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "delete this->ptr_;" << nl; - *ci << "this->ptr_ = 0;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - // copy constructor - ci->indent (); - *ci << "ACE_INLINE" << nl; - *ci << fname << "::" << lname << " (const " << fname << - " &p) // copy constructor" << nl; - *ci << " : ptr_ (ACE_const_cast (" << fname << "&,p).ptr_)" << nl; - *ci << "{}\n\n"; - - // assignment operator from _out & - ci->indent (); - *ci << "ACE_INLINE " << fname << " &" << nl; - *ci << fname << "::operator= (const " << fname << - " &p)" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "this->ptr_ = ACE_const_cast (" << fname << "&,p).ptr_;" << nl; - *ci << "return *this;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - // assignment from _var is not allowed by a private declaration - - // assignment operator from pointer - ci->indent (); - *ci << "ACE_INLINE " << fname << " &" << nl; - *ci << fname << "::operator= (" << this->name () << - " *p)" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "this->ptr_ = p;" << nl; - *ci << "return *this;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - // other extra methods - cast operator () - ci->indent (); - *ci << "ACE_INLINE " << nl; - *ci << fname << "::operator " << this->name () << - " *&() // cast" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "return this->ptr_;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - // ptr function - ci->indent (); - *ci << "ACE_INLINE " << this->name () << " *&" << nl; - *ci << fname << "::ptr (void) // ptr" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "return this->ptr_;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - // operator -> - ci->indent (); - *ci << "ACE_INLINE " << this->name () << " *" << nl; - *ci << fname << "::operator-> (void)" << nl; - *ci << "{\n"; - ci->incr_indent (); - *ci << "return this->ptr_;\n"; - ci->decr_indent (); - *ci << "}\n\n"; - - - return 0; -} - -// compute the size type of the node in question -int -be_union::compute_size_type (void) -{ - UTL_ScopeActiveIterator *si; - AST_Decl *d; - be_decl *bd; - - if (this->nmembers () > 0) - { - // if there are elements in this scope - - si = new UTL_ScopeActiveIterator (this, UTL_Scope::IK_decls); - // instantiate a scope iterator. - - while (!(si->is_done ())) - { - // get the next AST decl node - d = si->item (); - bd = be_decl::narrow_from_decl (d); - if (bd != 0) - { - // 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 (bd->size_type ()); - } - else - { - ACE_DEBUG ((LM_DEBUG, - "WARNING (%N:%l) be_union::compute_size_type - " - "narrow_from_decl returned 0\n")); - } - si->next (); - } // end of while - delete si; // free the iterator object - } - return 0; -} - -// Are we or the parameter node involved in any recursion -idl_bool -be_union::in_recursion (be_type *node) -{ - if (!node) - { - // we are determining the recursive status for ourselves - node = this; - } - - // proceed if the number of members in our scope is greater than 0 - if (this->nmembers () > 0) - { - // initialize an iterator to iterate thru our scope - UTL_ScopeActiveIterator *si; - ACE_NEW_RETURN (si, - UTL_ScopeActiveIterator (this, - UTL_Scope::IK_decls), - -1); - // continue until each element is visited - while (!si->is_done ()) - { - be_union_branch *field = be_union_branch::narrow_from_decl (si->item ()); - if (!field) - { - delete si; - ACE_ERROR_RETURN ((LM_ERROR, - ASYS_TEXT ("(%N:%l) be_union::") - ASYS_TEXT ("in_recursion - ") - ASYS_TEXT ("bad field node\n")), - 0); - } - be_type *type = be_type::narrow_from_decl (field->field_type ()); - if (!type) - { - delete si; - ACE_ERROR_RETURN ((LM_ERROR, - ASYS_TEXT ("(%N:%l) be_union::") - ASYS_TEXT ("in_recursion - ") - ASYS_TEXT ("bad field type\n")), - 0); - } - if (type->in_recursion (node)) - { - delete si; - return 1; - } - si->next (); - } // end of while loop - delete si; - } // end of if - - // not in recursion - return 0; -} - -// return the default value -int -be_union::default_value (be_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, - ASYS_TEXT ("(%N:%l) be_union::") - ASYS_TEXT ("default_value - ") - ASYS_TEXT ("Error computing ") - ASYS_TEXT ("default value\n")), - -1); - } - } - dv = this->default_value_; - return 0; -} - -// determine the implicit default value (if any) -int -be_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. - UTL_ScopeActiveIterator *si - = new UTL_ScopeActiveIterator (this, UTL_Scope::IK_decls); - while (!(si->is_done ())) - { - // get the next AST decl node - be_union_branch *ub = be_union_branch::narrow_from_decl (si->item ()); - if (ub) - { - // 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++; - } - } - si->next (); - } - delete si; - - // 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, - ASYS_TEXT ("(%N:%l) be_union::compute_default_value ") - ASYS_TEXT ("- unimplemented discriminant type ") - ASYS_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_bool: - if (total_case_members == 2) - this->default_value_.computed_ = 0; - break; - case AST_Expression::EV_any: - // has to be enum - { - be_decl *d = be_decl::narrow_from_decl (this->disc_type ()); - if (d->node_type () == AST_Decl::NT_typedef) - { - be_typedef *bt = be_typedef::narrow_from_decl (d); - d = bt->primitive_base_type (); - } - be_enum *en = be_enum::narrow_from_decl (d); - if (en) - { - if (total_case_members == en->member_count ()) - this->default_value_.computed_ = 0; - } - else - { - // error - this->default_value_.computed_ = -1; - ACE_ERROR_RETURN ((LM_ERROR, - ASYS_TEXT ("(%N:%l) be_union::") - ASYS_TEXT ("compute_default_value ") - ASYS_TEXT ("- disc type not an ENUM\n")), - -1); - } - } - break; - default: - // error - this->default_value_.computed_ = -1; - ACE_ERROR_RETURN ((LM_ERROR, - ASYS_TEXT ("(%N:%l) be_union::compute_default_value ") - ASYS_TEXT ("- Bad discriminant type\n")), - -1); - ACE_NOTREACHED (break;) - } // end of switch - - // if we have determined that we don't need 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, - ASYS_TEXT ("(%N:%l) be_union::compute_default_value ") - ASYS_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: - this->default_value_.u.long_val = ACE_INT32_MIN; - 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_bool: - this->default_value_.u.bool_val = 0; - break; - case AST_Expression::EV_any: - this->default_value_.u.enum_val = 0; - break; - case AST_Expression::EV_longlong: - case AST_Expression::EV_ulonglong: - // unimplemented - default: - // error caught earlier. - break; - } // end of switch - - // proceed until we have found the appropriate default value - while (this->default_value_.computed_ == -2) - { - si = new UTL_ScopeActiveIterator (this, UTL_Scope::IK_decls); - // instantiate a scope iterator. - - int break_loop = 0; - - while (!(si->is_done ()) && !break_loop) - { - // get the next AST decl node - be_union_branch *ub = be_union_branch::narrow_from_decl (si->item ()); - if (ub) - { - 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) - { - // error - this->default_value_.computed_ = -1; - ACE_ERROR_RETURN - ((LM_ERROR, - ASYS_TEXT ("(%N:%l) be_union::") - ASYS_TEXT ("compute_default_value - ") - ASYS_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_bool: - if (this->default_value_.u.bool_val - == expr->ev ()->u.bval) - { - this->default_value_.u.bool_val++; - break_loop = 1; - } - break; - case AST_Expression::EV_any: - // 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 - si->next (); - } // end of while scope iterator loop - delete si; // free the iterator object - - // we have not aborted the inner loops which means we have found the - // default value - if (!break_loop) - this->default_value_.computed_ = 1; - - } // end of outer while - - return 0; -} - -// visitor method - -int -be_union::accept (be_visitor *visitor) -{ - return visitor->visit_union (this); -} - -// Narrowing -IMPL_NARROW_METHODS3 (be_union, AST_Union, be_scope, be_type) -IMPL_NARROW_FROM_DECL (be_union) -IMPL_NARROW_FROM_SCOPE (be_union) |