diff options
author | gokhale <asgokhale@users.noreply.github.com> | 1999-05-15 14:34:34 +0000 |
---|---|---|
committer | gokhale <asgokhale@users.noreply.github.com> | 1999-05-15 14:34:34 +0000 |
commit | 5b741b72bb190b602d2e9acf437cff08cd641eff (patch) | |
tree | 8f772a5c1bdb8809fc318cfa3622d4ad0fd85b80 | |
parent | b531ef278d781aae3765d5f3132e3b0b1e07cde8 (diff) | |
download | ATCD-5b741b72bb190b602d2e9acf437cff08cd641eff.tar.gz |
recursive/optimized typecodes
67 files changed, 3687 insertions, 1528 deletions
diff --git a/TAO/ChangeLog-99c b/TAO/ChangeLog-99c index c5f91faec61..77fa8efce8d 100644 --- a/TAO/ChangeLog-99c +++ b/TAO/ChangeLog-99c @@ -1,3 +1,230 @@ +Sat May 15 10:22:52 EDT 1999 Aniruddha Gokhale <gokhale@sahyadri.research.bell-labs.com> + + * TAO_IDL/be/be_array.cpp: + TAO_IDL/be_include/be_array.h: + TAO_IDL/be/be_enum.cpp: + TAO_IDL/be_include/be_enum.h: + TAO_IDL/be/be_enum_val.cpp: + TAO_IDL/be_include/be_enum_val.h: + TAO_IDL/be/be_exception.cpp: + TAO_IDL/be_include/be_exception.h: + TAO_IDL/be/be_field.cpp: + TAO_IDL/be_include/be_field.h: + TAO_IDL/be/be_interface.cpp: + TAO_IDL/be_include/be_interface.h: + TAO_IDL/be/be_interface_fwd.cpp: + TAO_IDL/be_include/be_interface_fwd.h: + TAO_IDL/be/be_predefined_type.cpp: + TAO_IDL/be_include/be_predefined_type.h: + TAO_IDL/be/be_scope.cpp: + TAO_IDL/be_include/be_scope.h: + TAO_IDL/be/be_sequence.cpp: + TAO_IDL/be_include/be_sequence.h: + TAO_IDL/be/be_string.cpp: + TAO_IDL/be_include/be_string.h: + TAO_IDL/be/be_structure.cpp: + TAO_IDL/be_include/be_structure.h: + TAO_IDL/be/be_typedef.cpp: + TAO_IDL/be_include/be_typedef.h: + TAO_IDL/be/be_union.cpp: + TAO_IDL/be_include/be_union.h: + TAO_IDL/be/be_union_branch.cpp: + TAO_IDL/be_include/be_union_branch.h: + + Removed the gen_encapsulation, gen_typecode, tc_size, and + tc_encap_len methods. All this has been moved to the typecode + visitor (be_visitor_typecode_defn). + + * TAO_IDL/be/be_decl.cpp: + TAO_IDL/be_include/be_decl.h: + + Removed the data members encap_len_, and the methods + gen_encapsulation, gen_typecode, tc_encap_len, tc_size, + tc_name2long, repoID_encap_len, and name_encap_len. All this has + been moved to the be_visitor_typecode_defn visitor. + + * TAO_IDL/be/be_helper.cpp: + TAO_IDL/be_include/be_helper.h: + + Added more operator<< for various ACE_CDR types. + + * TAO_IDL/be/be_sequence.cpp: + TAO_IDL/be_include/be_sequence.h: + TAO_IDL/be/be_structure.cpp: + TAO_IDL/be_include/be_structure.h: + TAO_IDL/be/be_type.cpp: + TAO_IDL/be_include/be_type.h: + TAO_IDL/be/be_union.cpp: + TAO_IDL/be_include/be_union.h: + + Added a method (in_recursion) that returns a boolean result that + indicates whether the sequence's element type is involved in a + direct or indirect recursion. An example of such a scenario is: + + struct foo + { + // other fields + sequence <foo> bar; + }; + + The be_type's in_recursion method always returns 0 because all + other subclasses of be_type except be_sequence, be_structure, + and be_union will never be involved in the limited recursion + allowed by the CORBA spec. + + * TAO_IDL/be/be_visitor_typecode.cpp: + + Added explicit template instantiations for templates used in the + typecode_defn.cpp file. See below. + + * TAO_IDL/be/be_visitor_argument_post_docall_cs.cpp: + + In the visit interface method, we were not handling the out + type. Now we correctly narrow the type and release the base type. + + * TAO_IDL/be/be_visitor_array/cdr_op_cs.cpp: + TAO_IDL/be/be_visitor_attribute/attribute.cpp: + TAO_IDL/be/be_visitor_sequence/cdr_op_cs.cpp: + + Added default cases to switch statements to eliminate warnings + produced by EGCS about enums not handled. + + * TAO_IDL/be_include/be_codegen.h: + + Added new substate enumerations for use in typecode generation. + + * TAO_IDL/be/be_valuetype.cpp: + TAO_IDL/be_include/be_valuetype.h: + + Commented out the typecode related methods. These need to be + added later to the typecode visitor. This is still TO-DO. + + * TAO_IDL/be/be_visitor_enum/enum_cs.cpp: + TAO_IDL/be/be_visitor_enum/exception_cs.cpp: + TAO_IDL/be/be_visitor_enum/interface_cs.cpp: + TAO_IDL/be/be_visitor_enum/structure_cs.cpp: + TAO_IDL/be/be_visitor_enum/typedef_cs.cpp: + TAO_IDL/be/be_visitor_enum/union_cs.cpp: + + Added a step where we set the context substate to typecode + generation. This way we can then generate the top-level typecode + encapsulation for the type we are dealing with. Nested typecodes + are then generated by the visitor itself by setting the + appropriate substate. + + * TAO_IDL/be/be_visitor_operation/operation_cs.cpp: + + Rearranged the invocation of the POST_INVOKE_CS + visitor. Otherwise some code was getting duplicated. + This was also necessary because for interpreted marshaling, we + had to do some cleaning up of local variables. However, this was + not required for the compiled marshaling stubs. + + * TAO_IDL/be/be_visitor_sequence/sequence_ch.cpp: + TAO_IDL/be/be_visitor_sequence/sequence_cs.cpp: + + Commented out the code that generates typecodes for anonymous + sequences. Once we are sure that nothing breaks, we will remove + this code. + + * TAO_IDL/be/be_visitor_typecode/typecode_defn.cpp: + TAO_IDL/be_include/be_visitor_typecode/typecode_defn.h: + + All the typecode generation is now handled by this visitor + rather than individual files such as be_array.cpp, and + others. Added all the methods for typecode generation such as + gen_typecode, gen_encapsulation, tc_size, tc_encap_len, + repoID_encap_len, name_ID_len, and name2long. Also added data + members to track the computed sizes. We were required to add all + the visit_* methods to deal with all the types. + + The most prominent addition to this visitor is the capability to + generate typecodes for recursive types and the ability to + generate optimized typecodes. Optimized typecodes use sharing of + typecodes for repeated types. This is achieved via + indirections. We do not optimize for typecodes of primitive + types. + + * TAO_IDL/be/be_visitor_union_branch/public_access.cpp + (visit_interface): + + The access method for object references was incorrect. We have + now come up we a new way of returning the value from the acces + method. In particular, instead of casting the value to + CORBA::Object_ptr and then to void *, we simply return a pointer + to TAO_Object_Field_T<TYPE>. In the decode and encode methods of + the marshaling engine (see ChangeLog entry below), we invoke the + appropriate upcast method to give us the right CORBA::Object_ptr + value. This fix has now led to successful working of the + Param_Test test for obj references that use interpretive + marshaling. + + * TAO_IDL/driver/drv_args.cpp: + + Enabled optimized typecode handling. Also, we were checking for + -Go option instead of -Gt option. This is now fixed. + + * tao/CDR_Interpreter.cpp: + + Handled indirected streams properly so that it will allow us to + cross encapsulation boundaries. Previously, it wouldn't allow us + to do so. + + * tao/Typecode.h: + tao/Typecode.cpp: + + Added two data members called tc_base_ and root_tc_base_. The + tc_base_ points to our tk_kind field in the CDR + representation. The root_tc_base_ is for children typecodes + (i.e., nested typecodes who have parents) and it points to the + tk_kind field of the topmost level typecode. + + Also note that in the CTOR for complex typecodes, we now + allocate 8 bytes in addition to the length parameter. The first + two words occupy the top-level typecode's tk_kind value and the + encapsulation length. The buffer_ member still points to the + encapsulation so that no other change in the entire file is + required. The reason why we had to have these extra 8 bytes at + the start is to handle the recursive typecodes. For example + + struct foo + { + // fields + sequence <foo> bar; + }; + + The encaspulation for the above will generate an indirection + whose offset will point to the tk_kind field of "foo". However, + prior to the change described here, we only maintained the CDR + representation of the encapsulation. So the offset would have + pointed to 8 bytes before the encapsulation which really diod + not exist. We would have required unnecessary code to handle + such a case. So the best way was to maintain the entire typecode + representation. + + * tao/decode.cpp: + tao/encode.cpp: + + Indirected streams are now constructed properly such that we can + cross encapsulation boundaries. We were not required to make any + changes to the CTORs of ACE_InputCDR. + + We also properly handle the object reference fields of + unions. The access method gives us a TAO_Object_Field_T<> + pointer and then we invoke the _upcast method to give us the + CORBA::Object_ptr. + + * tests/Param_Test/param_test.idl: + tests/Param_Test/big_union.cpp: + + cosmetic changes. + + TO-DO + + for anonymous sequences whose element type gives rise to a + recursion, we must generate the <<, >> compiled marshaling + operators in the *.cpp file else we get a circular dependency. + Fri May 14 23:55:47 1999 Jeff Parsons <parsons@cs.wustl.edu> * tao/Request.{h,i,cpp}: diff --git a/TAO/TAO_IDL/be/be_array.cpp b/TAO/TAO_IDL/be/be_array.cpp index 34c77c9e340..dac2ad3fc56 100644 --- a/TAO/TAO_IDL/be/be_array.cpp +++ b/TAO/TAO_IDL/be/be_array.cpp @@ -218,117 +218,6 @@ be_array::gen_dimensions (TAO_OutStream *os, unsigned short slice) return 0; } -int -be_array::gen_typecode (void) -{ - TAO_OutStream *os; // output stream - - os = tao_cg->client_stubs (); - os->indent (); // start from whatever indentation level we were at - - *os << "CORBA::tk_array, // typecode kind" << be_nl; - *os << this->tc_encap_len () << ", // encapsulation length" << be_idt << "\n"; - // now emit the encapsulation - if (this->gen_encapsulation () == -1) - { - } - // *os << (this->dims () [0]) << "," << be_nl; - return 0; -} - -// generate encapsulation -// An encapsulation for ourselves will be necessary when we are part of some -// other IDL type and a typecode for that other type is being generated. This -// will comprise our typecode kind. IDL types with parameters will additionally -// have the encapsulation length and the entire typecode description - -int -be_array::gen_encapsulation (void) -{ - TAO_OutStream *os; // output stream - be_type *bt; // base type - unsigned long i; - - os = tao_cg->client_stubs (); - os->indent (); // start from the current indentation level - - // retrieve the base type - bt = be_type::narrow_from_decl (this->base_type ()); - if (!bt) - { - ACE_ERROR_RETURN ((LM_ERROR, - "(%N:%l) be_array::gen_encapsulation - " - "bad base type\n"), - -1); - } - - for (i=0; i < (this->n_dims () - 1); i++) - { - unsigned long rem_encap_len; - - *os << "TAO_ENCAP_BYTE_ORDER, // byte order" << be_nl; - *os << "CORBA::tk_array, // typecode kind" << be_nl; - rem_encap_len - = (this->n_dims () - (i+1))*(4+4) - + (this->n_dims () - (i+2))*(4+4) - + bt->tc_size (); - *os << rem_encap_len << ", // encapsulation length" << be_idt_nl; - } - *os << "TAO_ENCAP_BYTE_ORDER, // byte order\n"; - if (bt->gen_typecode () == -1) - { - ACE_ERROR_RETURN ((LM_ERROR, - "(%N:%l) be_array::gen_encapsulation - " - "base type tyepcode gen failed\n"), - -1); - } - os->indent (); - for (i = (this->n_dims ()-1); i > 0; i--) - { - *os << this->dims ()[i] << "," << be_uidt_nl; - } - *os << this->dims ()[0] << be_uidt << ",\n"; - return 0; -} - -// compute typecode size -long -be_array::tc_size (void) -{ - // 4 bytes for enumeration, 4 bytes for storing encap length val, followed by the - // actual encapsulation - return 4 + 4 + this->tc_encap_len (); -} - -long -be_array::tc_encap_len (void) -{ - // Suppose "N" is the number of dimensions, then for a N dimensional array, - // we will have N encapsulations. The innermost encapsulation will hold the - // typecode of the real base type. - // Thus, we will have N byte order flags and dimensions, and N-1 tk_array - // enumerations, encapsulation lengths, and dimensions. - - if (this->encap_len_ == -1) // not computed yet - { - be_type *bt; // base type - - bt = be_type::narrow_from_decl (this->base_type ()); - if (!bt) - { - ACE_ERROR ((LM_ERROR, - "be_array::tc_encap_len - bad base type\n")); - return 0; - } - this->encap_len_ = - this->n_dims () * (4+4) // N byte order flags and dims - + (this->n_dims ()-1)* (4+4); // N-1 of Enum and encap lengths - // to this you add the typecode size of the underlying type - this->encap_len_ += bt->tc_size (); - } - return this->encap_len_; -} - // compute the size type of the node in question int be_array::compute_size_type (void) diff --git a/TAO/TAO_IDL/be/be_decl.cpp b/TAO/TAO_IDL/be/be_decl.cpp index b11ee3133ff..cf488f0f387 100644 --- a/TAO/TAO_IDL/be/be_decl.cpp +++ b/TAO/TAO_IDL/be/be_decl.cpp @@ -44,8 +44,7 @@ be_decl::be_decl (void) flatname_ (0), repoID_ (0), prefix_ (0), - size_type_ (be_decl::SIZE_UNKNOWN), - encap_len_ (-1) + size_type_ (be_decl::SIZE_UNKNOWN) { } @@ -70,8 +69,7 @@ be_decl::be_decl (AST_Decl::NodeType type, flatname_ (0), repoID_ (0), prefix_ (0), - size_type_ (be_decl::SIZE_UNKNOWN), - encap_len_ (-1) + size_type_ (be_decl::SIZE_UNKNOWN) { } @@ -80,19 +78,6 @@ be_decl::~be_decl (void) { } -int -be_decl::gen_encapsulation (void) -{ - // do nothing - return 0; -} - -long -be_decl::tc_encap_len (void) -{ - return -1; -} - // return our size type be_decl::SIZE_TYPE be_decl::size_type (void) @@ -417,29 +402,6 @@ be_decl::prefix (void) return this->prefix_; } -// converts a string name into an array of 4 byte longs -int -be_decl::tc_name2long (const char *name, ACE_UINT32 *&larr, long &arrlen) -{ - const int bytes_per_word = sizeof(ACE_UINT32); - static ACE_UINT32 buf [NAMEBUFSIZE]; - long slen; - long i; - - slen = ACE_OS::strlen (name) + 1; // 1 for NULL terminating - - // compute the number of bytes necessary to hold the name rounded to - // the next multiple of 4 (i.e., size of long) - arrlen = slen / bytes_per_word + (slen % bytes_per_word ? 1:0); - - ACE_OS::memset (buf, 0, sizeof(buf)); - larr = buf; - ACE_OS::memcpy (buf, name, slen); - for (i = 0; i < arrlen; i++) - larr [i] = ACE_HTONL (larr [i]); - return 0; -} - idl_bool be_decl::is_nested (void) { @@ -454,35 +416,6 @@ be_decl::is_nested (void) return I_FALSE; } -// return the length in bytes to hold the repoID inside a typecode. This -// comprises 4 bytes indicating the length of the string followed by the actual -// string represented as longs. -long -be_decl::repoID_encap_len (void) -{ - long slen; - - slen = ACE_OS::strlen (this->repoID ()) + 1; // + 1 for NULL terminating char - // the number of bytes to hold the string must be a multiple of 4 since this - // will be represented as an array of longs - return 4 + 4 * (slen/4 + (slen%4 ? 1:0)); -} - -// return the length in bytes to hold the name inside a typecode. This -// comprises 4 bytes indicating the length of the string followed by the actual -// string represented as longs. -long -be_decl::name_encap_len (void) -{ - long slen; - - slen = ACE_OS::strlen (this->local_name ()->get_string ()) + 1; - - // the number of bytes to hold the string must be a multiple of 4 since this - // will be represented as an array of longs - return 4 + 4 * (slen/4 + (slen%4 ? 1:0)); -} - // compute the size type of the node in question int be_decl::compute_size_type (void) diff --git a/TAO/TAO_IDL/be/be_enum.cpp b/TAO/TAO_IDL/be/be_enum.cpp index e80f8704cf0..335301785f5 100644 --- a/TAO/TAO_IDL/be/be_enum.cpp +++ b/TAO/TAO_IDL/be/be_enum.cpp @@ -82,101 +82,6 @@ be_enum::member_count (void) return this->member_count_; } - -// generate typecode. -// Typecode for enum comprises the enumerated value followed by the -// encapsulation of the parameters - -int -be_enum::gen_typecode (void) -{ - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - *cs << "CORBA::tk_enum, // typecode kind" << nl; - *cs << this->tc_encap_len () << ", // encapsulation length\n"; - // now emit the encapsulation - return this->gen_encapsulation (); -} - -int -be_enum::gen_encapsulation (void) -{ - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - long i, arrlen; - - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - *cs << "TAO_ENCAP_BYTE_ORDER, // byte order" << nl; - // generate repoID - *cs << (ACE_OS::strlen (this->repoID ())+1) << ", "; - - ACE_UINT32 *arr; - (void)this->tc_name2long (this->repoID (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // repository ID = " << this->repoID () << nl; - // generate name - *cs << (ACE_OS::strlen (this->local_name ()->get_string ())+1) << ", "; - (void)this->tc_name2long(this->local_name ()->get_string (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // name = " << this->local_name () << nl; - // generate the member count - *cs << this->member_count () << ", // member count\n"; - cs->incr_indent (0); - // hand over to the scope to generate the typecode for elements - if (be_scope::gen_encapsulation () == -1) - { - ACE_ERROR ((LM_ERROR, "be_structure: cannot generate code for members\n")); - return -1; - } - cs->decr_indent (0); - return 0; -} - -// compute typecode size -long -be_enum::tc_size (void) -{ - // 4 bytes for enumeration, 4 bytes for storing encap length val, followed by the - // actual encapsulation length - return 4 + 4 + this->tc_encap_len (); -} - -// return encapsulation length -long -be_enum::tc_encap_len (void) -{ - if (this->encap_len_ == -1) // not computed yet - { - this->encap_len_ = 4; // holds the byte order flag - - this->encap_len_ += this->repoID_encap_len (); // repoID storage - - // do the same thing for the local name - this->encap_len_ += this->name_encap_len (); - - this->encap_len_ += 4; // to hold the member count - - // compute encap length for members - this->encap_len_ += be_scope::tc_encap_len (); - } - return this->encap_len_; -} - int be_enum::accept (be_visitor *visitor) { diff --git a/TAO/TAO_IDL/be/be_enum_val.cpp b/TAO/TAO_IDL/be/be_enum_val.cpp index 3a52a779278..3fcd99fdd6f 100644 --- a/TAO/TAO_IDL/be/be_enum_val.cpp +++ b/TAO/TAO_IDL/be/be_enum_val.cpp @@ -40,39 +40,6 @@ be_enum_val::be_enum_val (unsigned long v, UTL_ScopedName *n, UTL_StrList *p) } int -be_enum_val::gen_encapsulation (void) -{ - TAO_OutStream *cs; // output stream - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - long i, arrlen; - ACE_UINT32 *arr; - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - // generate name - *cs << (ACE_OS::strlen (this->local_name ()->get_string ())+1) << ", "; - (void)this->tc_name2long(this->local_name ()->get_string (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // name = " << this->local_name () << "\n"; - return 0; -} - -long -be_enum_val::tc_encap_len (void) -{ - if (this->encap_len_ == -1) // not computed yet - { - this->encap_len_ = this->name_encap_len (); // for name - } - - return this->encap_len_; -} - -int be_enum_val::accept (be_visitor *visitor) { return visitor->visit_enum_val (this); diff --git a/TAO/TAO_IDL/be/be_exception.cpp b/TAO/TAO_IDL/be/be_exception.cpp index 9c788ce25b6..d39abd6b4e4 100644 --- a/TAO/TAO_IDL/be/be_exception.cpp +++ b/TAO/TAO_IDL/be/be_exception.cpp @@ -78,109 +78,60 @@ be_exception::member_count (void) return this->member_count_; } -// generate typecode. -// Typecode for exceptions comprises the enumerated value followed by the -// encapsulation of the parameters - -int -be_exception::gen_typecode (void) +// Are we or the parameter node involved in any recursion +idl_bool +be_exception::in_recursion (be_type *node) { - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - *cs << "CORBA::tk_except, // typecode kind" << nl; - *cs << this->tc_encap_len () << ", // encapsulation length\n"; - // now emit the encapsulation - cs->incr_indent (0); - if (this->gen_encapsulation () == -1) + if (!node) { - return -1; + // we are determining the recursive status for ourselves + node = this; } - cs->decr_indent (); - return 0; -} -// generate encapsulation -// An encapsulation for ourselves will be necessary when we are part of some -// other IDL type and a typecode for that other type is being generated. This -// will comprise our typecode kind. IDL types with parameters will additionally -// have the encapsulation length and the entire typecode description -int -be_exception::gen_encapsulation (void) -{ - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - long i, arrlen; - ACE_UINT32 *arr; - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - // XXXASG - byte order must be based on what m/c we are generating code - - // TODO - *cs << "TAO_ENCAP_BYTE_ORDER, // byte order" << nl; - // generate repoID - *cs << (ACE_OS::strlen (this->repoID ())+1) << ", "; - (void)this->tc_name2long (this->repoID (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // repository ID = " << this->repoID () << nl; - // generate name - *cs << (ACE_OS::strlen (this->local_name ()->get_string ())+1) << ", "; - (void)this->tc_name2long(this->local_name ()->get_string (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // name = " << this->local_name () << nl; - // generate the member count - *cs << this->member_count () << ", // member count\n"; - cs->incr_indent (0); - // hand over to the scope to generate the typecode for elements - if (be_scope::gen_encapsulation () == -1) - { - ACE_ERROR ((LM_ERROR, "be_exception: cannot generate typecode for members\n")); - return -1; - } - cs->decr_indent (0); - return 0; -} - -// compute typecode size -long -be_exception::tc_size (void) -{ - // 4 bytes for enumeration, 4 bytes for storing encap length val, followed by the - // actual encapsulation length - return 4 + 4 + this->tc_encap_len (); -} - -// compute encapsulation length -long -be_exception::tc_encap_len (void) -{ - if (this->encap_len_ == -1) // not computed yet + // proceed if the number of members in our scope is greater than 0 + if (this->nmembers () > 0) { - this->encap_len_ = 4; // holds the byte order flag - - this->encap_len_ += this->repoID_encap_len (); // repoID - - // do the same thing for the local name - this->encap_len_ += this->name_encap_len (); - - this->encap_len_ += 4; // to hold the member count + // 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_field *field = be_field::narrow_from_decl (si->item ()); + if (!field) + { + delete si; + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_exception::") + 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_exception::") + 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 - // compute encap length for members - this->encap_len_ += be_scope::tc_encap_len (); - } - return this->encap_len_; + // not in recursion + return 0; } int diff --git a/TAO/TAO_IDL/be/be_field.cpp b/TAO/TAO_IDL/be/be_field.cpp index 8ecf2c88468..6b9a4d2e143 100644 --- a/TAO/TAO_IDL/be/be_field.cpp +++ b/TAO/TAO_IDL/be/be_field.cpp @@ -38,51 +38,6 @@ be_field::be_field (AST_Type *ft, UTL_ScopedName *n, UTL_StrList *p, Visibility { } -int -be_field::gen_encapsulation (void) -{ - TAO_OutStream *cs; // output stream - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - be_type *bt; // our type node - long i, arrlen; - ACE_UINT32 *arr; - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - // generate name - *cs << (ACE_OS::strlen (this->local_name ()->get_string ())+1) << ", "; - (void)this->tc_name2long(this->local_name ()->get_string (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // name = " << this->local_name () << "\n"; - - // hand over code generation to our type node - bt = be_type::narrow_from_decl (this->field_type ()); - return bt->gen_typecode (); -} - -long -be_field::tc_encap_len (void) -{ - if (this->encap_len_ == -1) // not computed yet - { - be_type *bt; - - // struct member is represented as the "name" followed by the typecode - - this->encap_len_ = this->name_encap_len (); // for name - - // add to this, the size of our typecode - bt = be_type::narrow_from_decl (this->field_type ()); - this->encap_len_ += bt->tc_size (); // note that we must add typecode - // size of the type - } - return this->encap_len_; -} - // compute the size type of the node in question int be_field::compute_size_type (void) diff --git a/TAO/TAO_IDL/be/be_helper.cpp b/TAO/TAO_IDL/be/be_helper.cpp index 85b268cbffa..3a039fcfb30 100644 --- a/TAO/TAO_IDL/be/be_helper.cpp +++ b/TAO/TAO_IDL/be/be_helper.cpp @@ -166,7 +166,7 @@ TAO_OutStream::indent (void) // spaces in the output if (this->indent_level_ > 0) { - for (i=0; i < this->indent_level_; i++) + for (i = 0; i < this->indent_level_; i++) { ACE_OS::fprintf (this->fp_, " "); ACE_OS::fflush (this->fp_); @@ -224,6 +224,8 @@ TAO_OutStream::gen_ifdef_macro (const char *flatname, const char *suffix) case TAO_OutStream::TAO_SVR_IMPL: ACE_OS::strcat (macro, "SS_"); break; + default: + return -1; } *this << "\n#if !defined (" << macro << ")\n"; *this << "#define " << macro << "\n\n"; @@ -288,6 +290,46 @@ TAO_OutStream::operator<< (const char *str) } TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::UShort num) +{ + ACE_OS::fprintf (this->fp_, "%hu", num); + ACE_OS::fflush (fp_); + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::Short num) +{ + ACE_OS::fprintf (this->fp_, "%hd", num); + ACE_OS::fflush (fp_); + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::ULong num) +{ + ACE_OS::fprintf (this->fp_, "%lu", num); + ACE_OS::fflush (fp_); + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const ACE_CDR::Long num) +{ + ACE_OS::fprintf (this->fp_, "%ld", num); + ACE_OS::fflush (fp_); + return *this; +} + +TAO_OutStream & +TAO_OutStream::operator<< (const unsigned long num) +{ + ACE_OS::fprintf (this->fp_, "%lu", num); + ACE_OS::fflush (fp_); + return *this; +} + +TAO_OutStream & TAO_OutStream::operator<< (const long num) { ACE_OS::fprintf (this->fp_, "%ld", num); diff --git a/TAO/TAO_IDL/be/be_interface.cpp b/TAO/TAO_IDL/be/be_interface.cpp index 35a1dd9211a..b926dfc27d4 100644 --- a/TAO/TAO_IDL/be/be_interface.cpp +++ b/TAO/TAO_IDL/be/be_interface.cpp @@ -804,95 +804,6 @@ be_interface::gen_out_impl (void) return 0; } -// generate typecode. -// Typecode for interface comprises the enumerated value followed by the -// encapsulation of the parameters - -int -be_interface::gen_typecode (void) -{ - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - *cs << "CORBA::tk_objref, // typecode kind" << nl; - *cs << this->tc_encap_len () << ", // encapsulation length\n"; - // now emit the encapsulation - return this->gen_encapsulation (); -} - -// generate encapsulation -// An encapsulation for ourselves will be necessary when we are part of some -// other IDL type and a typecode for that other type is being generated. This -// will comprise our typecode kind. IDL types with parameters will additionally -// have the encapsulation length and the entire typecode description -int -be_interface::gen_encapsulation (void) -{ - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - long i, arrlen; - ACE_UINT32 *arr; - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - // XXXASG - byte order must be based on what m/c we are generating code - - // TODO - *cs << "TAO_ENCAP_BYTE_ORDER, // byte order" << nl; - // generate repoID - *cs << (ACE_OS::strlen (this->repoID ())+1) << ", "; - (void)this->tc_name2long (this->repoID (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // repository ID = " << this->repoID () << nl; - // generate name - *cs << (ACE_OS::strlen (this->local_name ()->get_string ())+1) << ", "; - (void)this->tc_name2long(this->local_name ()->get_string (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // name = " << this->local_name () << ",\n"; - - return 0; -} - -// compute size of typecode -long -be_interface::tc_size (void) -{ - return 4 + 4 + this->tc_encap_len (); -} - -// compute the encapsulation length -long -be_interface::tc_encap_len (void) -{ - if (this->encap_len_ == -1) // not computed yet - { - long slen; - - // Macro to avoid "warning: unused parameter" type warning. - ACE_UNUSED_ARG (slen); - - this->encap_len_ = 4; // holds the byte order flag - - this->encap_len_ += this->repoID_encap_len (); // for repoID - - // do the same thing for the local name - this->encap_len_ += this->name_encap_len (); - - } - return this->encap_len_; -} - // helper. int be_interface::gen_operation_table (void) diff --git a/TAO/TAO_IDL/be/be_interface_fwd.cpp b/TAO/TAO_IDL/be/be_interface_fwd.cpp index 2083c4c2925..37b043c003c 100644 --- a/TAO/TAO_IDL/be/be_interface_fwd.cpp +++ b/TAO/TAO_IDL/be/be_interface_fwd.cpp @@ -500,17 +500,6 @@ be_interface_fwd::gen_out_impl (void) return 0; } -int -be_interface_fwd::gen_typecode (void) -{ - return 0; -} - -long -be_interface_fwd::tc_size (void) -{ - return 0; -} int be_interface_fwd::accept (be_visitor *visitor) diff --git a/TAO/TAO_IDL/be/be_predefined_type.cpp b/TAO/TAO_IDL/be/be_predefined_type.cpp index 4ca417ca519..4541f60d37a 100644 --- a/TAO/TAO_IDL/be/be_predefined_type.cpp +++ b/TAO/TAO_IDL/be/be_predefined_type.cpp @@ -282,149 +282,6 @@ be_predefined_type::compute_tc_name (void) } } -int -be_predefined_type::gen_typecode (void) -{ - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - - // Macro to avoid "warning: unused parameter" type warning. - ACE_UNUSED_ARG (nl); - - cs = cg->client_stubs (); - cs->indent (); // start from the current indentation level - - switch (this->pt ()) - { - case AST_PredefinedType::PT_void: - *cs << "CORBA::tk_void,\n\n"; - break; - case AST_PredefinedType::PT_short: - *cs << "CORBA::tk_short,\n\n"; - break; - case AST_PredefinedType::PT_ushort: - *cs << "CORBA::tk_ushort,\n\n"; - break; - case AST_PredefinedType::PT_long: - *cs << "CORBA::tk_long,\n\n"; - break; - case AST_PredefinedType::PT_ulong: - *cs << "CORBA::tk_ulong,\n\n"; - break; - case AST_PredefinedType::PT_longlong: - *cs << "CORBA::tk_longlong,\n\n"; - break; - case AST_PredefinedType::PT_ulonglong: - *cs << "CORBA::tk_ulonglong,\n\n"; - break; - case AST_PredefinedType::PT_float: - *cs << "CORBA::tk_float,\n\n"; - break; - case AST_PredefinedType::PT_double: - *cs << "CORBA::tk_double,\n\n"; - break; - case AST_PredefinedType::PT_longdouble: - *cs << "CORBA::tk_longdouble,\n\n"; - break; - case AST_PredefinedType::PT_boolean: - *cs << "CORBA::tk_boolean,\n\n"; - break; - case AST_PredefinedType::PT_char: - *cs << "CORBA::tk_char,\n\n"; - break; - case AST_PredefinedType::PT_octet: - *cs << "CORBA::tk_octet,\n\n"; - break; - case AST_PredefinedType::PT_any: - *cs << "CORBA::tk_any,\n\n"; - break; - case AST_PredefinedType::PT_wchar: - *cs << "CORBA::tk_wchar,\n\n"; - break; - case AST_PredefinedType::PT_pseudo: - { - if (!ACE_OS::strcmp (this->local_name ()->get_string (), "TypeCode")) - *cs << "CORBA::tk_TypeCode,\n\n"; - else - if (!ACE_OS::strcmp (this->local_name ()->get_string (), "Object")) - { - *cs << "CORBA::tk_objref,\n"; - *cs << this->tc_encap_len () << ", // encapsulation length\n"; - // now emit the encapsulation - this->gen_encapsulation (); - } - } - break; - } - return 0; -} - -long -be_predefined_type::tc_size (void) -{ - if (ACE_OS::strcmp (this->local_name ()->get_string (), "Object")) // not same - return 4; // for the enum value - else - return 4 + 4 + this->tc_encap_len (); -} - -long -be_predefined_type::tc_encap_len (void) -{ - if ((this->encap_len_ == -1) // not computed yet - && (!ACE_OS::strcmp (this->local_name ()->get_string (), "Object"))) - // is a CORBA::Object - { - this->encap_len_ = 4; // holds the byte order flag - - this->encap_len_ += this->repoID_encap_len (); // for repoID - - // do the same thing for the local name - this->encap_len_ += this->name_encap_len (); - } - - return this->encap_len_; -} - -int -be_predefined_type::gen_encapsulation (void) -{ - if ((this->pt () == AST_PredefinedType::PT_any) - || (this->pt () == AST_PredefinedType::PT_pseudo)) - { - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - long i, arrlen; - ACE_UINT32 *arr; - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - // XXXASG - byte order must be based on what m/c we are generating code - - // TODO - *cs << "TAO_ENCAP_BYTE_ORDER, // byte order" << nl; - // generate repoID - *cs << (ACE_OS::strlen (this->repoID ())+1) << ", "; - (void)this->tc_name2long (this->repoID (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // repository ID = " << this->repoID () << nl; - // generate name - *cs << (ACE_OS::strlen (this->local_name ()->get_string ())+1) << ", "; - (void)this->tc_name2long(this->local_name ()->get_string (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // name = " << this->local_name () << ",\n"; - } - return 0; -} - // compute the size type of the node in question int be_predefined_type::compute_size_type (void) diff --git a/TAO/TAO_IDL/be/be_scope.cpp b/TAO/TAO_IDL/be/be_scope.cpp index 24d3eb1daf4..16dfb2defe9 100644 --- a/TAO/TAO_IDL/be/be_scope.cpp +++ b/TAO/TAO_IDL/be/be_scope.cpp @@ -38,79 +38,6 @@ be_scope::comma (void) const return this->comma_; } -int -be_scope::gen_encapsulation (void) -{ - UTL_ScopeActiveIterator *si; - AST_Decl *d; - be_decl *bd; - - // 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 (); - bd = be_decl::narrow_from_decl (d); - if (bd->gen_encapsulation () == -1) - { - // failure - return -1; - } - si->next (); - } // end of while - delete si; // free the iterator object - } - return 0; -} - -long -be_scope::tc_encap_len (void) -{ - UTL_ScopeActiveIterator *si; - AST_Decl *d; - be_decl *bd; - long encap_len = 0; - - 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 (); - - // NOTE: Our assumptin here is that whatever scope we are in, the - // node type that shows up here *MUST* be valid according to the - // IDL grammar. We do not check for this since the front end must - // have taken care of weeding out such errors - - bd = be_decl::narrow_from_decl (d); - if (bd != 0) - { - encap_len += bd->tc_encap_len (); - } - else - { - ACE_DEBUG ((LM_DEBUG, - "WARNING (%N:%l): be_scope::tc_encap_len - " - "narrow_from_decl returned 0\n")); - } - si->next (); - } // end of while - delete si; // free the iterator object - } - return encap_len; -} - // return the scope created by this node (if one exists, else NULL) be_decl * be_scope::decl (void) diff --git a/TAO/TAO_IDL/be/be_sequence.cpp b/TAO/TAO_IDL/be/be_sequence.cpp index 2fca004ea58..5cbb7686b39 100644 --- a/TAO/TAO_IDL/be/be_sequence.cpp +++ b/TAO/TAO_IDL/be/be_sequence.cpp @@ -213,90 +213,6 @@ be_sequence::managed_type (void) return this->mt_; } -// generate typecode. -// Typecode for sequences comprises the enumerated value followed by the -// encapsulation of the parameters - -int -be_sequence::gen_typecode (void) -{ - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - *cs << "CORBA::tk_sequence, // typecode kind" << nl; - *cs << this->tc_encap_len () << ", // encapsulation length\n"; - // now emit the encapsulation - return this->gen_encapsulation (); -} - -// generate encapsulation -// An encapsulation for ourselves will be necessary when we are part of some -// other IDL type and a typecode for that other type is being generated. This -// will comprise our typecode kind. IDL types with parameters will additionally -// have the encapsulation length and the entire typecode description - -int -be_sequence::gen_encapsulation (void) -{ - TAO_OutStream *os; // output stream - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - be_type *bt; // base type - - os = cg->client_stubs (); - os->incr_indent (); - - *os << "TAO_ENCAP_BYTE_ORDER, // byte order\n"; - - // emit typecode of element type - bt = be_type::narrow_from_decl (this->base_type ()); - if (!bt || (bt->gen_typecode () == -1)) - { - ACE_ERROR ((LM_ERROR, "be_sequence::gen_typecode - bad base type\n")); - return -1; - } - - // emit the length - os->decr_indent (); - *os << this->max_size () << ",\n"; - return 0; -} - -// compute typecode size -long -be_sequence::tc_size (void) -{ - // 4 bytes for enumeration, 4 bytes for storing encap length val, followed by the - // actual encapsulation length - return 4 + 4 + this->tc_encap_len (); -} - -long -be_sequence::tc_encap_len (void) -{ - if (this->encap_len_ == -1) // not computed yet - { - be_type *bt; // base type - - this->encap_len_ = 4; // holds the byte order flag - // add the encapsulation length of our base type - bt = be_type::narrow_from_decl (this->base_type ()); - if (!bt) - { - ACE_ERROR ((LM_ERROR, - "be_sequence::tc_encap_len - bad base type\n")); - return 0; - } - this->encap_len_ += bt->tc_size (); - this->encap_len_ += 4; // to hold the max size - - } - return this->encap_len_; -} - /* * Add this be_sequence to the locally defined types in this scope */ @@ -446,6 +362,37 @@ be_sequence::object_manager_name () } +idl_bool +be_sequence::in_recursion (be_type *node) +{ + if (!node) + { + // there has to be a parameter + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_sequence::") + ASYS_TEXT ("in_recursion - ") + ASYS_TEXT ("bad parameter node\n")), + 0); + } + + be_type *type = be_type::narrow_from_decl (this->base_type ()); + if (!type) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_sequence::") + ASYS_TEXT ("in_recursion - ") + ASYS_TEXT ("bad base type\n")), + 0); + } + + if (!ACE_OS::strcmp (node->fullname (), type->fullname ())) + // they match + return 1; + else + // not in recursion + return 0; +} + // Narrowing IMPL_NARROW_METHODS3 (be_sequence, AST_Sequence, be_scope, be_type) IMPL_NARROW_FROM_DECL (be_sequence) diff --git a/TAO/TAO_IDL/be/be_string.cpp b/TAO/TAO_IDL/be/be_string.cpp index ba4a3c87277..4d72f2ab761 100644 --- a/TAO/TAO_IDL/be/be_string.cpp +++ b/TAO/TAO_IDL/be/be_string.cpp @@ -73,45 +73,6 @@ be_string::compute_tc_name (void) } int -be_string::gen_typecode (void) -{ - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - - cs = cg->client_stubs (); - cs->indent (); // start from the current indentation level - // emit the enumeration - *cs << "CORBA::tk_string, " << nl; - *cs << this->max_size () << ", // string length\n"; - return 0; -} - -// compute typecode size -long -be_string::tc_size (void) -{ - // 4 bytes for enumeration, 4 bytes for storing string length - return 4 + 4; -} - -int -be_string::gen_encapsulation (void) -{ - return 0; -} - -long -be_string::tc_encap_len (void) -{ - if (this->encap_len_ == -1) - { - this->encap_len_ = 0; // no encapsulation - } - return this->encap_len_; -} - -int be_string::accept (be_visitor *visitor) { return visitor->visit_string (this); diff --git a/TAO/TAO_IDL/be/be_structure.cpp b/TAO/TAO_IDL/be/be_structure.cpp index 3073c59e1f3..df04d665cae 100644 --- a/TAO/TAO_IDL/be/be_structure.cpp +++ b/TAO/TAO_IDL/be/be_structure.cpp @@ -564,109 +564,6 @@ be_structure::gen_out_impl (void) return 0; } -// generate typecode. -// Typecode for structures comprises the enumerated value followed by the -// encapsulation of the parameters - -int -be_structure::gen_typecode (void) -{ - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - *cs << "CORBA::tk_struct, // typecode kind" << nl; - *cs << this->tc_encap_len () << ", // encapsulation length\n"; - // now emit the encapsulation - cs->incr_indent (0); - if (this->gen_encapsulation () == -1) - { - return -1; - } - cs->decr_indent (); - return 0; -} - -// generate encapsulation -// An encapsulation for ourselves will be necessary when we are part of some -// other IDL type and a typecode for that other type is being generated. This -// will comprise our typecode kind. IDL types with parameters will additionally -// have the encapsulation length and the entire typecode description -int -be_structure::gen_encapsulation (void) -{ - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - long i, arrlen; - ACE_UINT32 *arr; - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - *cs << "TAO_ENCAP_BYTE_ORDER, // byte order" << nl; - // generate repoID - *cs << (ACE_OS::strlen (this->repoID ())+1) << ", "; - (void)this->tc_name2long (this->repoID (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // repository ID = " << this->repoID () << nl; - // generate name - *cs << (ACE_OS::strlen (this->local_name ()->get_string ())+1) << ", "; - (void)this->tc_name2long(this->local_name ()->get_string (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // name = " << this->local_name () << nl; - // generate the member count - *cs << this->member_count () << ", // member count\n"; - cs->incr_indent (0); - // hand over to the scope to generate the typecode for elements - if (be_scope::gen_encapsulation () == -1) - { - ACE_ERROR ((LM_ERROR, "be_structure: cannot generate typecode for members\n")); - return -1; - } - cs->decr_indent (0); - return 0; -} - -// compute typecode size -long -be_structure::tc_size (void) -{ - // 4 bytes for enumeration, 4 bytes for storing encap length val, followed by the - // actual encapsulation length - return 4 + 4 + this->tc_encap_len (); -} - -// compute encapsulation length -long -be_structure::tc_encap_len (void) -{ - if (this->encap_len_ == -1) // not computed yet - { - this->encap_len_ = 4; // holds the byte order flag - - this->encap_len_ += this->repoID_encap_len (); // repoID - - // do the same thing for the local name - this->encap_len_ += this->name_encap_len (); - - this->encap_len_ += 4; // to hold the member count - - // compute encap length for members - this->encap_len_ += be_scope::tc_encap_len (); - } - return this->encap_len_; -} - // compute the size type of the node in question int be_structure::compute_size_type (void) @@ -708,6 +605,62 @@ be_structure::compute_size_type (void) return 0; } +// Are we or the parameter node involved in any recursion +idl_bool +be_structure::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_field *field = be_field::narrow_from_decl (si->item ()); + if (!field) + { + delete si; + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_structure::") + 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_structure::") + 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; +} + int be_structure::accept (be_visitor *visitor) { diff --git a/TAO/TAO_IDL/be/be_type.cpp b/TAO/TAO_IDL/be/be_type.cpp index 19c96513ca8..3e8f126c4bf 100644 --- a/TAO/TAO_IDL/be/be_type.cpp +++ b/TAO/TAO_IDL/be/be_type.cpp @@ -279,6 +279,13 @@ AST_Decl::NodeType be_type::base_node_type (void) const return ACE_const_cast(be_type*, this)->node_type (); } +idl_bool +be_type::in_recursion (be_type *) +{ + // be default we are not involved in recursion + return 0; +} + int be_type::accept (be_visitor *visitor) { diff --git a/TAO/TAO_IDL/be/be_typedef.cpp b/TAO/TAO_IDL/be/be_typedef.cpp index f07db98f150..5fa56ef674b 100644 --- a/TAO/TAO_IDL/be/be_typedef.cpp +++ b/TAO/TAO_IDL/be/be_typedef.cpp @@ -54,108 +54,6 @@ be_typedef::primitive_base_type (void) return d; } -int -be_typedef::gen_typecode (void) -{ - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - *cs << "CORBA::tk_alias, // typecode kind for typedefs" << nl; - *cs << this->tc_encap_len () << ", // encapsulation length\n"; - // now emit the encapsulation - cs->incr_indent (0); - if (this->gen_encapsulation () == -1) - { - return -1; - } - - cs->decr_indent (0); - return 0; -} - -// generate encapsulation. A typedef is an alias to its base type -int -be_typedef::gen_encapsulation (void) -{ - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - long i, arrlen; - ACE_UINT32 *arr; - be_type *bt; // base type - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - *cs << "TAO_ENCAP_BYTE_ORDER, // byte order" << nl; - // generate repoID - *cs << (ACE_OS::strlen (this->repoID ())+1) << ", "; - (void)this->tc_name2long (this->repoID (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // repository ID = " << this->repoID () << nl; - - // generate name - *cs << (ACE_OS::strlen (this->local_name ()->get_string ())+1) << ", "; - (void)this->tc_name2long(this->local_name ()->get_string (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // name = " << this->local_name () << "\n"; - - // generate typecode for the base type - bt = be_type::narrow_from_decl (this->base_type ()); - if (!bt || (bt->gen_typecode () == -1)) - { - ACE_ERROR_RETURN ((LM_ERROR, - "be_typedef::gen_encapsulation failed for base type\n"), - -1); - } - return 0; -} - -long -be_typedef::tc_size (void) -{ - // 4 bytes for enumeration, 4 bytes for storing encap length val, followed by the - // actual encapsulation length - return 4 + 4 + this->tc_encap_len (); -} - -long -be_typedef::tc_encap_len (void) -{ - if (this->encap_len_ == -1) // not computed yet - { - be_type *bt; // base type - this->encap_len_ = 4; // holds the byte order flag - - this->encap_len_ += this->repoID_encap_len (); // repoID - - // do the same thing for the local name - this->encap_len_ += this->name_encap_len (); - - // add the encapsulation length of our base type - bt = be_type::narrow_from_decl (this->base_type ()); - if (!bt) - { - ACE_ERROR ((LM_ERROR, - "be_typedef::tc_encap_len - bad base type\n")); - return 0; - } - this->encap_len_ += bt->tc_size (); - - } - return this->encap_len_; -} - // compute the size type of the node in question int be_typedef::compute_size_type (void) diff --git a/TAO/TAO_IDL/be/be_union.cpp b/TAO/TAO_IDL/be/be_union.cpp index 6a07d15fd6a..b33c214f9a3 100644 --- a/TAO/TAO_IDL/be/be_union.cpp +++ b/TAO/TAO_IDL/be/be_union.cpp @@ -618,123 +618,6 @@ be_union::gen_out_impl (void) return 0; } -int -be_union::gen_typecode (void) -{ - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - *cs << "CORBA::tk_union, // typecode kind" << nl; - *cs << this->tc_encap_len () << ", // encapsulation length\n"; - // now emit the encapsulation - return this->gen_encapsulation (); -} - -// generate encapsulation. -// An encapsulation for ourselves will be necessary when we are part of some -// other IDL type and a typecode for that other type is being generated. This -// will comprise our typecode kind. IDL types with parameters will additionally -// have the encapsulation length and the entire typecode description - -int -be_union::gen_encapsulation (void) -{ - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - long i, arrlen; - ACE_UINT32 *arr; - be_type *discrim; - - cs = cg->client_stubs (); - cs->indent (); // start from whatever indentation level we were at - - *cs << "TAO_ENCAP_BYTE_ORDER, // byte order" << nl; - // generate repoID - *cs << (ACE_OS::strlen (this->repoID ())+1) << ", "; - (void)this->tc_name2long (this->repoID (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // repository ID = " << this->repoID () << nl; - // generate name - *cs << (ACE_OS::strlen (this->local_name ()->get_string ())+1) << ", "; - (void)this->tc_name2long(this->local_name ()->get_string (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // name = " << this->local_name () << ",\n"; - - // generate typecode for discriminant - discrim = be_type::narrow_from_decl (this->disc_type ()); - if (discrim->gen_typecode () == -1) - { - ACE_ERROR ((LM_ERROR, "be_union: cannot generate typecode for discriminant\n")); - return -1; - } - - // generate the default used flag - cs->indent (); - *cs << this->default_index () << ", // default used index" << nl; - // generate the member count - *cs << this->member_count () << ", // member count\n"; - cs->incr_indent (0); - // hand over to the scope to generate the typecode for elements - if (be_scope::gen_encapsulation () == -1) - { - ACE_ERROR ((LM_ERROR, "be_union: cannot generate code for members\n")); - return -1; - } - cs->decr_indent (0); - return 0; -} - -// compute typecode size -long -be_union::tc_size (void) -{ - // 4 bytes for enumeration, 4 bytes for storing encap length val, followed by the - // actual encapsulation length - return 4 + 4 + this->tc_encap_len (); -} - -long -be_union::tc_encap_len (void) -{ - if (this->encap_len_ == -1) // not computed yet - { - long slen; - be_type *discrim; - - // Macro to avoid "warning: unused parameter" type warning. - ACE_UNUSED_ARG (slen); - - this->encap_len_ = 4; // holds the byte order flag - - this->encap_len_ += this->repoID_encap_len (); // for repoID - - // do the same thing for the local name - this->encap_len_ += this->name_encap_len (); // for name - - // add encapsulation size of discriminant typecode - discrim = be_type::narrow_from_decl (this->disc_type ()); - this->encap_len_ += discrim->tc_size (); - - this->encap_len_ += 4; // to hold the "default used" flag - this->encap_len_ += 4; // to hold the member count - - // compute encap length for members - this->encap_len_ += be_scope::tc_encap_len (); - } - return this->encap_len_; -} - // compute the size type of the node in question int be_union::compute_size_type (void) @@ -776,6 +659,62 @@ be_union::compute_size_type (void) 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; +} + int be_union::accept (be_visitor *visitor) { diff --git a/TAO/TAO_IDL/be/be_union_branch.cpp b/TAO/TAO_IDL/be/be_union_branch.cpp index 3523a45b408..c6c2d44d392 100644 --- a/TAO/TAO_IDL/be/be_union_branch.cpp +++ b/TAO/TAO_IDL/be/be_union_branch.cpp @@ -41,99 +41,6 @@ be_union_branch::be_union_branch (AST_UnionLabel *lab, AST_Type *ft, { } -int -be_union_branch::gen_encapsulation (void) -{ - TAO_OutStream *cs; // output stream - TAO_NL nl; // end line - TAO_CodeGen *cg = TAO_CODEGEN::instance (); - be_type *bt; // our type node - long i, arrlen; - ACE_UINT32 *arr; - - cs = cg->client_stubs (); - - *cs << be_nl; - - // be_union* the_union = - // be_union::narrow_from_scope (this->defined_in ()); - - ACE_UINT32 buf[1]; - ACE_OS::memset (buf, 0, sizeof (buf)); - - // emit the case label value - AST_Expression *expression = this->label ()->label_val (); - AST_Expression::AST_ExprValue *ev = expression->ev (); - switch (ev->et) // the_union->udisc_type ()) - { - case AST_Expression::EV_char: - case AST_Expression::EV_bool: - cs->print ("ACE_IDL_NCTOHL (0x%02.2x)", (unsigned char)ev->u.cval); - break; - - case AST_Expression::EV_wchar: - case AST_Expression::EV_short: - case AST_Expression::EV_ushort: - cs->print ("ACE_IDL_NSTOHL (0x%04.4x)", (unsigned short)ev->u.sval); - break; - - case AST_Expression::EV_long: - case AST_Expression::EV_ulonglong: - *cs << expression; - break; - - default: - if (expression->ec () == AST_Expression::EC_symbol) - { - *cs << expression; - } - else - { - ACE_ERROR_RETURN ((LM_ERROR, - "be_union_branch: (%N:%l) Label value " - "type (%d) is invalid\n", ev->et), -1); - } - break; - } - - *cs << ", // union case label (evaluated)" << nl; - // emit name - *cs << (ACE_OS::strlen (this->local_name ()->get_string ())+1) << ", "; - (void)this->tc_name2long(this->local_name ()->get_string (), arr, arrlen); - for (i=0; i < arrlen; i++) - { - cs->print ("ACE_NTOHL (0x%x), ", arr[i]); - } - *cs << " // name = " << this->local_name () << "\n"; - - // hand over code generation to our type node - bt = be_type::narrow_from_decl (this->field_type ()); - if (!bt) - return -1; - return bt->gen_typecode (); -} - -long -be_union_branch::tc_encap_len (void) -{ - if (this->encap_len_ == -1) - { - be_type *bt; - - this->encap_len_ = 4; // case label; - this->encap_len_ += this->name_encap_len (); // for name - bt = be_type::narrow_from_decl (this->field_type ()); - if (!bt) - { - ACE_ERROR ((LM_ERROR, "be_union_branch: bad field type\n")); - return -1; - } - this->encap_len_ += bt->tc_size (); // note that we add the typecode size - // of the type - } - return this->encap_len_; -} - // compute the size type of the node in question int be_union_branch::compute_size_type (void) diff --git a/TAO/TAO_IDL/be/be_valuetype.cpp b/TAO/TAO_IDL/be/be_valuetype.cpp index 118d600046a..57c7006417b 100644 --- a/TAO/TAO_IDL/be/be_valuetype.cpp +++ b/TAO/TAO_IDL/be/be_valuetype.cpp @@ -588,6 +588,7 @@ be_valuetype::gen_out_impl (void) return 0; } +#if 0 // generate typecode. // Typecode for interface comprises the enumerated value followed by the // encapsulation of the parameters @@ -684,6 +685,7 @@ be_valuetype::tc_encap_len (void) } return this->encap_len_; } +#endif // for building the pre and postfix of private data fields const char* diff --git a/TAO/TAO_IDL/be/be_visitor_argument/post_docall_cs.cpp b/TAO/TAO_IDL/be/be_visitor_argument/post_docall_cs.cpp index 0a1d2d4dbd1..9aa12d3295c 100644 --- a/TAO/TAO_IDL/be/be_visitor_argument/post_docall_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_argument/post_docall_cs.cpp @@ -85,6 +85,7 @@ be_visitor_args_post_docall_cs::visit_interface (be_interface *node) switch (this->direction ()) { case AST_Argument::dir_INOUT: + case AST_Argument::dir_OUT: { os->indent (); // assign the narrowed obj reference diff --git a/TAO/TAO_IDL/be/be_visitor_array/cdr_op_cs.cpp b/TAO/TAO_IDL/be/be_visitor_array/cdr_op_cs.cpp index ee2d0ac34f7..520731d3a16 100644 --- a/TAO/TAO_IDL/be/be_visitor_array/cdr_op_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_array/cdr_op_cs.cpp @@ -293,6 +293,13 @@ be_visitor_array_cdr_op_cs::visit_predefined_type (be_predefined_type *node) case TAO_CodeGen::TAO_CDR_OUTPUT: *os << " ((const char *)_tao_array.in (), "; break; + default: + // error + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_array_cdr_op_cs::" + "visit_predefined_type - " + "bad substate in context\n"), + -1); } break; default: @@ -304,6 +311,13 @@ be_visitor_array_cdr_op_cs::visit_predefined_type (be_predefined_type *node) case TAO_CodeGen::TAO_CDR_OUTPUT: *os << " (_tao_array.in (), "; break; + default: + // error + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_array_cdr_op_cs::" + "visit_predefined_type - " + "bad substate in context\n"), + -1); } break; } @@ -488,6 +502,13 @@ be_visitor_array_cdr_op_cs::visit_node (be_type *bt) *os << ".out ()"; } } + default: + // error + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_array_cdr_op_cs::" + "visit_predefined_type - " + "bad node type\n"), + -1); } if (bt->node_type () == AST_Decl::NT_array) { @@ -534,6 +555,13 @@ be_visitor_array_cdr_op_cs::visit_node (be_type *bt) *os << ".in ()"; } } + default: + // error + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_array_cdr_op_cs::" + "visit_predefined_type - " + "bad node type\n"), + -1); } if (bt->node_type () == AST_Decl::NT_array) { diff --git a/TAO/TAO_IDL/be/be_visitor_attribute/attribute.cpp b/TAO/TAO_IDL/be/be_visitor_attribute/attribute.cpp index 19c2f374eea..719daab6d35 100644 --- a/TAO/TAO_IDL/be/be_visitor_attribute/attribute.cpp +++ b/TAO/TAO_IDL/be/be_visitor_attribute/attribute.cpp @@ -110,6 +110,13 @@ be_visitor_attribute::visit_attribute (be_attribute *node) case TAO_CodeGen::TAO_ATTRIBUTE_TIE_SI: ctx.state (TAO_CodeGen::TAO_OPERATION_TIE_SI); break; + default: + // error + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_attribute::" + "visit_attribute - " + "bad codegen state\n"), + -1); } be_visitor *visitor = tao_cg->make_visitor (&ctx); @@ -182,6 +189,13 @@ be_visitor_attribute::visit_attribute (be_attribute *node) case TAO_CodeGen::TAO_ATTRIBUTE_TIE_SI: ctx.state (TAO_CodeGen::TAO_OPERATION_TIE_SI); break; + default: + // error + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_attribute::" + "visit_attribute - " + "bad codegen state\n"), + -1); } visitor = tao_cg->make_visitor (&ctx); diff --git a/TAO/TAO_IDL/be/be_visitor_enum/enum_cs.cpp b/TAO/TAO_IDL/be/be_visitor_enum/enum_cs.cpp index 254939b0378..fde3be596e2 100644 --- a/TAO/TAO_IDL/be/be_visitor_enum/enum_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_enum/enum_cs.cpp @@ -53,6 +53,7 @@ be_visitor_enum_cs::visit_enum (be_enum *node) be_visitor *visitor; be_visitor_context ctx (*this->ctx_); ctx.state (TAO_CodeGen::TAO_TYPECODE_DEFN); + ctx.sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE); visitor = tao_cg->make_visitor (&ctx); if (!visitor || (node->accept (visitor) == -1)) { diff --git a/TAO/TAO_IDL/be/be_visitor_exception/exception_cs.cpp b/TAO/TAO_IDL/be/be_visitor_exception/exception_cs.cpp index 17aa786ba9f..3d78fa5387b 100644 --- a/TAO/TAO_IDL/be/be_visitor_exception/exception_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_exception/exception_cs.cpp @@ -193,6 +193,7 @@ int be_visitor_exception_cs::visit_exception (be_exception *node) // based on the command line options. This is still TO-DO ctx = *this->ctx_; ctx.state (TAO_CodeGen::TAO_TYPECODE_DEFN); + ctx.sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE); visitor = tao_cg->make_visitor (&ctx); if (!visitor || (node->accept (visitor) == -1)) { diff --git a/TAO/TAO_IDL/be/be_visitor_interface/interface_cs.cpp b/TAO/TAO_IDL/be/be_visitor_interface/interface_cs.cpp index 1f69360b1e6..41e5c6cb922 100644 --- a/TAO/TAO_IDL/be/be_visitor_interface/interface_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_interface/interface_cs.cpp @@ -163,6 +163,7 @@ be_visitor_interface_cs::visit_interface (be_interface *node) be_visitor *visitor; be_visitor_context ctx (*this->ctx_); ctx.state (TAO_CodeGen::TAO_TYPECODE_DEFN); + ctx.sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE); visitor = tao_cg->make_visitor (&ctx); if (!visitor || (node->accept (visitor) == -1)) { diff --git a/TAO/TAO_IDL/be/be_visitor_operation/operation_cs.cpp b/TAO/TAO_IDL/be/be_visitor_operation/operation_cs.cpp index 9df843f51c1..60a9a9cd553 100644 --- a/TAO/TAO_IDL/be/be_visitor_operation/operation_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_operation/operation_cs.cpp @@ -222,20 +222,6 @@ be_visitor_operation_cs::visit_operation (be_operation *node) } - // do any post processing for the retval - ctx = *this->ctx_; - ctx.state (TAO_CodeGen::TAO_OPERATION_RETVAL_POST_INVOKE_CS); - visitor = tao_cg->make_visitor (&ctx); - if (!visitor || (bt->accept (visitor) == -1)) - { - delete visitor; - ACE_ERROR_RETURN ((LM_ERROR, - "(%N:%l) be_visitor_operation_cs::" - "visit_operation - " - "codegen for return type post do_static_call failed\n"), - -1); - } - if (!this->void_return_type (bt)) { // now generate the normal successful return statement @@ -592,10 +578,38 @@ be_interpretive_visitor_operation_cs::gen_marshal_and_invoke (be_operation "(%N:%l) be_interpretive_visitor_operation_cs::" "gen_marshal_and_invoke - " "codegen for checking exception failed\n"), - -1); + -1); } + // do any post processing for the arguments + ctx = *this->ctx_; + ctx.state (TAO_CodeGen::TAO_OPERATION_ARG_POST_INVOKE_CS); + visitor = tao_cg->make_visitor (&ctx); + if (!visitor || (node->accept (visitor) == -1)) + { + delete visitor; + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_operation_cs::" + "visit_operation - " + "codegen for args post do_static_call failed\n"), + -1); + } + + // do any post processing for the retval + ctx = *this->ctx_; + ctx.state (TAO_CodeGen::TAO_OPERATION_RETVAL_POST_INVOKE_CS); + visitor = tao_cg->make_visitor (&ctx); + if (!visitor || (bt->accept (visitor) == -1)) + { + delete visitor; + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_operation_cs::" + "visit_operation - " + "codegen for return type post do_static_call failed\n"), + -1); + } + return 0; } @@ -830,6 +844,7 @@ be_compiled_visitor_operation_cs::gen_marshal_and_invoke (be_operation // check if there was a user exception, else demarshal the // return val (if any) and parameters (if any) that came with // the response message + os->indent (); *os << "TAO_InputCDR &_tao_in = _tao_call.inp_stream ();" << be_nl << "if (!(\n" << be_idt << be_idt << be_idt; } diff --git a/TAO/TAO_IDL/be/be_visitor_sequence/cdr_op_cs.cpp b/TAO/TAO_IDL/be/be_visitor_sequence/cdr_op_cs.cpp index 26d99d9e015..78af3073c5f 100644 --- a/TAO/TAO_IDL/be/be_visitor_sequence/cdr_op_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_sequence/cdr_op_cs.cpp @@ -373,6 +373,13 @@ be_visitor_sequence_cdr_op_cs::visit_predefined_type (be_predefined_type *node) case TAO_CodeGen::TAO_CDR_OUTPUT: *os << " ((const char *)_tao_sequence.get_buffer (), "; break; + default: + // error + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_sequence_cdr_op_cs" + "::visit_predefined_type - " + "bad codegen substate\n"), + -1); } break; default: @@ -566,6 +573,8 @@ be_visitor_sequence_cdr_op_cs::visit_node (be_type *bt) *os << ".in ()"; } } + default: + break; } *os << ");"; break; diff --git a/TAO/TAO_IDL/be/be_visitor_sequence/sequence_ch.cpp b/TAO/TAO_IDL/be/be_visitor_sequence/sequence_ch.cpp index e256d530afa..d618daf3c56 100644 --- a/TAO/TAO_IDL/be/be_visitor_sequence/sequence_ch.cpp +++ b/TAO/TAO_IDL/be/be_visitor_sequence/sequence_ch.cpp @@ -363,6 +363,7 @@ int be_visitor_sequence_ch::visit_sequence (be_sequence *node) *os << "typedef " << node->local_name () << " *" << node->local_name () << "_ptr;\n"; +#if 0 if (!this->ctx_->tdef ()) { // by using a visitor to declare and define the TypeCode, we have the @@ -380,6 +381,7 @@ int be_visitor_sequence_ch::visit_sequence (be_sequence *node) ), -1); } } +#endif os->gen_endif (); // endif macro diff --git a/TAO/TAO_IDL/be/be_visitor_sequence/sequence_cs.cpp b/TAO/TAO_IDL/be/be_visitor_sequence/sequence_cs.cpp index 47d9d6f8a37..0a0ca1f7832 100644 --- a/TAO/TAO_IDL/be/be_visitor_sequence/sequence_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_sequence/sequence_cs.cpp @@ -271,6 +271,7 @@ int be_visitor_sequence_cs::visit_sequence (be_sequence *node) << " (void) // dtor" << be_nl << "{}\n\n"; +#if 0 if (!this->ctx_->tdef ()) { // by using a visitor to declare and define the TypeCode, we have the @@ -278,6 +279,7 @@ int be_visitor_sequence_cs::visit_sequence (be_sequence *node) // based on the command line options. This is still TO-DO ctx = *this->ctx_; ctx.state (TAO_CodeGen::TAO_TYPECODE_DEFN); + ctx.sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE); visitor = tao_cg->make_visitor (&ctx); if (!visitor || (node->accept (visitor) == -1)) { @@ -288,6 +290,7 @@ int be_visitor_sequence_cs::visit_sequence (be_sequence *node) ), -1); } } +#endif os->gen_endif (); node->cli_stub_gen (1); diff --git a/TAO/TAO_IDL/be/be_visitor_structure/structure_cs.cpp b/TAO/TAO_IDL/be/be_visitor_structure/structure_cs.cpp index 8ab877e8f35..830b5a7a0a3 100644 --- a/TAO/TAO_IDL/be/be_visitor_structure/structure_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_structure/structure_cs.cpp @@ -50,6 +50,7 @@ int be_visitor_structure_cs::visit_structure (be_structure *node) be_visitor *visitor; be_visitor_context ctx (*this->ctx_); ctx.state (TAO_CodeGen::TAO_TYPECODE_DEFN); + ctx.sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE); visitor = tao_cg->make_visitor (&ctx); if (!visitor || (node->accept (visitor) == -1)) { diff --git a/TAO/TAO_IDL/be/be_visitor_typecode.cpp b/TAO/TAO_IDL/be/be_visitor_typecode.cpp index 9267ece581e..5012a6f795b 100644 --- a/TAO/TAO_IDL/be/be_visitor_typecode.cpp +++ b/TAO/TAO_IDL/be/be_visitor_typecode.cpp @@ -30,3 +30,12 @@ ACE_RCSID(be, be_visitor_typecode, "$Id$") +#if defined (ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION) +template class ACE_Node<be_visitor_typecode_defn::QNode*>; +template class ACE_Unbounded_Queue<be_visitor_typecode_defn::QNode*>; +template class ACE_Unbounded_Queue_Iterator<be_visitor_typecode_defn::QNode*>; +#elif defined (ACE_HAS_TEMPLATE_INSTANTIATION_PRAGMA) +#pragma instantiate ACE_Node<be_visitor_typecode_defn::QNode*> +#pragma instantiate ACE_Unbounded_Queue<be_visitor_typecode_defn::QNode*> +#pragma instantiate ACE_Unbounded_Queue_Iterator<be_visitor_typecode_defn::QNode*> +#endif /* ACE_HAS_EXPLICIT_TEMPLATE_INSTANTIATION */ diff --git a/TAO/TAO_IDL/be/be_visitor_typecode/typecode_defn.cpp b/TAO/TAO_IDL/be/be_visitor_typecode/typecode_defn.cpp index f9e8584abeb..7742c75b478 100644 --- a/TAO/TAO_IDL/be/be_visitor_typecode/typecode_defn.cpp +++ b/TAO/TAO_IDL/be/be_visitor_typecode/typecode_defn.cpp @@ -32,12 +32,20 @@ ACE_RCSID(be_visitor_typecode, typecode_defn, "$Id$") // ****************************************************** be_visitor_typecode_defn::be_visitor_typecode_defn (be_visitor_context *ctx) - : be_visitor_decl (ctx) + : be_visitor_scope (ctx), + computed_tc_size_ (0), + computed_encap_len_ (0), + computed_scope_encap_len_ (0), + tc_offset_ (0), + index_ (-1) + { } be_visitor_typecode_defn::~be_visitor_typecode_defn (void) { + this->queue_reset (this->tc_queue_); + this->queue_reset (this->compute_queue_); } // the following needs to be done to deal with the most bizarre behavior of @@ -85,24 +93,57 @@ be_visitor_typecode_defn::gen_nested_namespace_end (be_module *node) return 0; } +// the visit methods will be called for the top-level node whose typecode is +// being generated + int be_visitor_typecode_defn::visit_type (be_type *node) { TAO_OutStream *os = this->ctx_->stream (); + const be_visitor_typecode_defn::QNode *qnode; + + // reset the queue + this->queue_reset (this->tc_queue_); + this->tc_offset_ = 0; + + // check if optimized typecodes are desired OR if the node is involved in + // some form of recursion + if (idl_global->opt_tc () || + node->in_recursion ()) + { + if ((qnode = this->queue_insert (this->tc_queue_, node, this->tc_offset_)) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_typecode_defn::" + "visit_type - " + "queue insert failed\n"), + -1); + } + } + + os->indent (); // start from current indentation level - os->indent (); // generate the typecode information here *os << "static const CORBA::Long _oc_" << node->flatname () << "[] =" << be_nl; *os << "{" << be_idt << "\n"; + + // add the sizeof the enum tk_* and the encap length that we do not put into + // this array but which will exist in the CDR buffer + + this->tc_offset_ = 4 + 4; + + // note that we just need the parameters here and hence we generate the // encapsulation for the parameters - if (node->gen_encapsulation () == -1) + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION); + if (node->accept (this) == -1) { ACE_ERROR_RETURN ((LM_ERROR, "(%N:%l) be_visitor_typecode_defn::" "visit_type - " - "codegen for typecode failed\n"), -1); + "codegen for typecode encapsulation failed\n"), + -1); } *os << be_uidt << "};" << be_nl; @@ -180,47 +221,2709 @@ be_visitor_typecode_defn::visit_type (be_type *node) int be_visitor_typecode_defn::visit_array (be_array *node) { - return this->visit_type (node); + switch (this->ctx_->sub_state ()) + { + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE: + return this->visit_type (node); + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED: + return this->gen_typecode (node); + case TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION: + return this->gen_encapsulation (node); + case TAO_CodeGen::TAO_TC_DEFN_TC_SIZE: + this->computed_tc_size_ = this->compute_tc_size (node); + return ((this->computed_tc_size_ > 0) ? 0 : -1); + case TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN: + this->computed_encap_len_ = this->compute_encap_length (node); + return ((this->computed_encap_len_ > 0) ? 0 : -1); + default: + // error + break; + } + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn::") + ASYS_TEXT ("visit - bad sub state ") + ASYS_TEXT ("in visitor context\n")), + -1); } int be_visitor_typecode_defn::visit_enum (be_enum *node) { - return this->visit_type (node); + switch (this->ctx_->sub_state ()) + { + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE: + return this->visit_type (node); + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED: + return this->gen_typecode (node); + case TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION: + return this->gen_encapsulation (node); + case TAO_CodeGen::TAO_TC_DEFN_TC_SIZE: + this->computed_tc_size_ = this->compute_tc_size (node); + return ((this->computed_tc_size_ > 0) ? 0 : -1); + case TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN: + this->computed_encap_len_ = this->compute_encap_length (node); + return ((this->computed_encap_len_ > 0) ? 0 : -1); + case TAO_CodeGen::TAO_TC_DEFN_SCOPE: + case TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN: + return this->visit_scope (node); + default: + // error + break; + } + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn::") + ASYS_TEXT ("visit - bad sub state ") + ASYS_TEXT ("in visitor context\n")), + -1); +} + +int +be_visitor_typecode_defn::visit_enum_val (be_enum_val *node) +{ + switch (this->ctx_->sub_state ()) + { + case TAO_CodeGen::TAO_TC_DEFN_SCOPE: + return this->gen_encapsulation (node); + case TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN: + this->computed_encap_len_ = this->compute_encap_length (node); + return ((this->computed_encap_len_ > 0) ? 0 : -1); + default: + // error + break; + } + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn::") + ASYS_TEXT ("visit - bad sub state ") + ASYS_TEXT ("in visitor context\n")), + -1); } int be_visitor_typecode_defn::visit_exception (be_exception *node) { - return this->visit_type (node); + switch (this->ctx_->sub_state ()) + { + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE: + return this->visit_type (node); + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED: + return this->gen_typecode (node); + case TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION: + return this->gen_encapsulation (node); + case TAO_CodeGen::TAO_TC_DEFN_TC_SIZE: + this->computed_tc_size_ = this->compute_tc_size (node); + return ((this->computed_tc_size_ > 0) ? 0 : -1); + case TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN: + this->computed_encap_len_ = this->compute_encap_length (node); + return ((this->computed_encap_len_ > 0) ? 0 : -1); + case TAO_CodeGen::TAO_TC_DEFN_SCOPE: + case TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN: + return this->visit_scope (node); + default: + // error + break; + } + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn::") + ASYS_TEXT ("visit - bad sub state ") + ASYS_TEXT ("in visitor context\n")), + -1); +} + +int +be_visitor_typecode_defn::visit_field (be_field *node) +{ + switch (this->ctx_->sub_state ()) + { + case TAO_CodeGen::TAO_TC_DEFN_SCOPE: + return this->gen_encapsulation (node); + case TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN: + this->computed_encap_len_ = this->compute_encap_length (node); + return ((this->computed_encap_len_ > 0) ? 0 : -1); + default: + // error + break; + } + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn::") + ASYS_TEXT ("visit - bad sub state ") + ASYS_TEXT ("in visitor context\n")), + -1); } int be_visitor_typecode_defn::visit_interface (be_interface *node) { - return this->visit_type (node); + switch (this->ctx_->sub_state ()) + { + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE: + return this->visit_type (node); + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED: + return this->gen_typecode (node); + case TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION: + return this->gen_encapsulation (node); + case TAO_CodeGen::TAO_TC_DEFN_TC_SIZE: + this->computed_tc_size_ = this->compute_tc_size (node); + return ((this->computed_tc_size_ > 0) ? 0 : -1); + case TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN: + this->computed_encap_len_ = this->compute_encap_length (node); + return ((this->computed_encap_len_ > 0) ? 0 : -1); + default: + // error + break; + } + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn::") + ASYS_TEXT ("visit - bad sub state ") + ASYS_TEXT ("in visitor context\n")), + -1); +} + +int +be_visitor_typecode_defn::visit_interface_fwd (be_interface_fwd *node) +{ + // nothing to do + return 0; +} + +int +be_visitor_typecode_defn::visit_predefined_type (be_predefined_type *node) +{ + switch (this->ctx_->sub_state ()) + { + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE: + // top level typecodes are defined in the CORBA library. If we show up + // here, then it is an error + break; + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED: + return this->gen_typecode (node); + case TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION: + return this->gen_encapsulation (node); + case TAO_CodeGen::TAO_TC_DEFN_TC_SIZE: + this->computed_tc_size_ = this->compute_tc_size (node); + return ((this->computed_tc_size_ > 0) ? 0 : -1); + case TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN: + this->computed_encap_len_ = this->compute_encap_length (node); + return ((this->computed_encap_len_ > 0) ? 0 : -1); + default: + // error + break; + } + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn::") + ASYS_TEXT ("visit - bad sub state ") + ASYS_TEXT ("in visitor context\n")), + -1); } int be_visitor_typecode_defn::visit_sequence (be_sequence *node) { - return this->visit_type (node); + switch (this->ctx_->sub_state ()) + { + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE: + return this->visit_type (node); + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED: + return this->gen_typecode (node); + case TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION: + return this->gen_encapsulation (node); + case TAO_CodeGen::TAO_TC_DEFN_TC_SIZE: + this->computed_tc_size_ = this->compute_tc_size (node); + return ((this->computed_tc_size_ > 0) ? 0 : -1); + case TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN: + this->computed_encap_len_ = this->compute_encap_length (node); + return ((this->computed_encap_len_ > 0) ? 0 : -1); + default: + // error + break; + } + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn::") + ASYS_TEXT ("visit - bad sub state ") + ASYS_TEXT ("in visitor context\n")), + -1); +} + +int +be_visitor_typecode_defn::visit_string (be_string *node) +{ + switch (this->ctx_->sub_state ()) + { + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE: + // top level typecode for string is not permitted. It has to be a + // typedefed string + break; + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED: + return this->gen_typecode (node); + case TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION: + return this->gen_encapsulation (node); + case TAO_CodeGen::TAO_TC_DEFN_TC_SIZE: + this->computed_tc_size_ = this->compute_tc_size (node); + return ((this->computed_tc_size_ > 0) ? 0 : -1); + case TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN: + this->computed_encap_len_ = this->compute_encap_length (node); + return ((this->computed_encap_len_ > 0) ? 0 : -1); + default: + // error + break; + } + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn::") + ASYS_TEXT ("visit - bad sub state ") + ASYS_TEXT ("in visitor context\n")), + -1); } int be_visitor_typecode_defn::visit_structure (be_structure *node) { - return this->visit_type (node); + switch (this->ctx_->sub_state ()) + { + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE: + return this->visit_type (node); + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED: + return this->gen_typecode (node); + case TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION: + return this->gen_encapsulation (node); + case TAO_CodeGen::TAO_TC_DEFN_TC_SIZE: + this->computed_tc_size_ = this->compute_tc_size (node); + return ((this->computed_tc_size_ > 0) ? 0 : -1); + case TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN: + this->computed_encap_len_ = this->compute_encap_length (node); + return ((this->computed_encap_len_ > 0) ? 0 : -1); + case TAO_CodeGen::TAO_TC_DEFN_SCOPE: + case TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN: + return this->visit_scope (node); + default: + // error + break; + } + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn::") + ASYS_TEXT ("visit - bad sub state ") + ASYS_TEXT ("in visitor context\n")), + -1); } int be_visitor_typecode_defn::visit_typedef (be_typedef *node) { - return this->visit_type (node); + switch (this->ctx_->sub_state ()) + { + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE: + return this->visit_type (node); + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED: + return this->gen_typecode (node); + case TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION: + return this->gen_encapsulation (node); + case TAO_CodeGen::TAO_TC_DEFN_TC_SIZE: + this->computed_tc_size_ = this->compute_tc_size (node); + return ((this->computed_tc_size_ > 0) ? 0 : -1); + case TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN: + this->computed_encap_len_ = this->compute_encap_length (node); + return ((this->computed_encap_len_ > 0) ? 0 : -1); + default: + // error + break; + } + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn::") + ASYS_TEXT ("visit - bad sub state ") + ASYS_TEXT ("in visitor context\n")), + -1); } int be_visitor_typecode_defn::visit_union (be_union *node) { - return this->visit_type (node); + switch (this->ctx_->sub_state ()) + { + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE: + return this->visit_type (node); + case TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED: + return this->gen_typecode (node); + case TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION: + return this->gen_encapsulation (node); + case TAO_CodeGen::TAO_TC_DEFN_TC_SIZE: + this->computed_tc_size_ = this->compute_tc_size (node); + return ((this->computed_tc_size_ > 0) ? 0 : -1); + case TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN: + this->computed_encap_len_ = this->compute_encap_length (node); + return ((this->computed_encap_len_ > 0) ? 0 : -1); + case TAO_CodeGen::TAO_TC_DEFN_SCOPE: + case TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN: + return this->visit_scope (node); + default: + // error + break; + } + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn::") + ASYS_TEXT ("visit - bad sub state ") + ASYS_TEXT ("in visitor context\n")), + -1); +} + +int +be_visitor_typecode_defn::visit_union_branch (be_union_branch *node) +{ + switch (this->ctx_->sub_state ()) + { + case TAO_CodeGen::TAO_TC_DEFN_SCOPE: + return this->gen_encapsulation (node); + case TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN: + this->computed_encap_len_ = this->compute_encap_length (node); + return ((this->computed_encap_len_ > 0) ? 0 : -1); + default: + // error + break; + } + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn::") + ASYS_TEXT ("visit - bad sub state ") + ASYS_TEXT ("in visitor context\n")), + -1); +} + +// methods that actually produce the typecode and the encapsulations + + +int +be_visitor_typecode_defn::gen_typecode (be_array *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + + os->indent (); // start from whatever indentation level we were at + + // we do not do typecode optimization for anonymous arrays + + *os << "CORBA::tk_array, // typecode kind" << be_nl; + // size of the enum + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // emit the encapsulation length + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) - be_visitor_typecode_defn") + ASYS_TEXT ("gen_typecode (array) - ") + ASYS_TEXT ("Failed to get encap length\n")), + -1); + } + *os << this->computed_encap_len_ << ", // encapsulation length" + << be_idt << "\n"; + // size of the encap length + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // now emit the encapsulation + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn::") + ASYS_TEXT ("gen_typecode - ") + ASYS_TEXT ("gen_encapsulation failed for array\n")), + -1); + } + + *os << be_uidt << "\n"; + + return 0; +} + +int +be_visitor_typecode_defn::gen_encapsulation (be_array *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + be_type *bt; // base type + unsigned long i; + + os->indent (); // start from the current indentation level + + // retrieve the base type + bt = be_type::narrow_from_decl (node->base_type ()); + if (!bt) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_array::gen_encapsulation - " + "bad base type\n"), + -1); + } + + // compute the typecode size + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_TC_SIZE); + if (bt->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) - be_visitor_typecode_defn") + ASYS_TEXT ("gen_encapsulation (array) - ") + ASYS_TEXT ("Failed to get typecode size\n")), + -1); + } + + for (i = 0; i < (node->n_dims () - 1); i++) + { + unsigned long rem_encap_len; + + *os << "TAO_ENCAP_BYTE_ORDER, // byte order" << be_nl; + // size of the encapsulation byte order flag. Although it is 1 byte, the + // aligned size is 4 bytes + this->tc_offset_ += sizeof (ACE_CDR::ULong); + *os << "CORBA::tk_array, // typecode kind" << be_nl; + // size of the enum + this->tc_offset_ += sizeof (ACE_CDR::ULong); + rem_encap_len + = (node->n_dims () - (i + 1)) * (4 + 4) + + (node->n_dims () - (i + 2)) * (4 + 4) + + this->computed_tc_size_; + *os << rem_encap_len << ", // encapsulation length" << be_idt_nl; + // size of the encap length + this->tc_offset_ += sizeof (ACE_CDR::ULong); + } + + // now generate the typecode of the base type + *os << "TAO_ENCAP_BYTE_ORDER, // byte order\n"; + // size of the encapsulation byte order flag. Although it is 1 byte, the + // aligned size is 4 bytes + this->tc_offset_ += sizeof (ACE_CDR::ULong); + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED); + if (bt->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_array::gen_encapsulation - " + "base type typecode gen failed\n"), + -1); + } + + os->indent (); + // now reduce the indentation appropriately + for (i = (node->n_dims () - 1); i > 0; i--) + { + *os << node->dims ()[i] << "," << be_uidt_nl; + // size of the dimension which is a 4 byte quantity + this->tc_offset_ += sizeof (ACE_CDR::ULong); + } + *os << node->dims ()[0] << ",\n"; + // size of the dimension which is a 4 byte quantity + this->tc_offset_ += sizeof (ACE_CDR::ULong); + return 0; +} + +int +be_visitor_typecode_defn::gen_typecode (be_enum *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + + os->indent (); // start from whatever indentation level we were at + + // check if we are repeated + const be_visitor_typecode_defn::QNode *qnode = + this->queue_lookup (this->tc_queue_, node); + if (qnode) + { + // we are repeated, so we must generate an indirection here + *os << "0xffffffff, // indirection" << be_nl; + this->tc_offset_ += sizeof (ACE_CDR::ULong); + // the offset must point to the tc_kind value of the first occurrence of + // this type + os->print ("0x%x, // negative offset (%ld)\n", + (qnode->offset - this->tc_offset_), + (qnode->offset - this->tc_offset_)); + this->tc_offset_ += sizeof (ACE_CDR::ULong); + } + else + { + if (idl_global->opt_tc ()) + { + if (this->queue_insert (this->tc_queue_, node, this->tc_offset_) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_typecode_defn::" + "visit_type - " + "queue insert failed\n"), + -1); + } + } + + *os << "CORBA::tk_enum, // typecode kind" << be_nl; + // size of the enum + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // reset the compute queue to set the stage for computing our + // encapsulation length + this->queue_reset (this->compute_queue_); + + // emit the encapsulation length + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) - be_visitor_typecode_defn") + ASYS_TEXT ("gen_typecode (enum) - ") + ASYS_TEXT ("Failed to get encap length\n")), + -1); + } + // reset the compute queue since we must not affect computation of other + // nodes + this->queue_reset (this->compute_queue_); + + *os << this->computed_encap_len_ << ", // encapsulation length" + << be_idt << "\n"; + // size of the encap length + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // now emit the encapsulation + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::gen_typecode (enum) - ") + ASYS_TEXT ("failed to generate encapsulation\n")), + -1); + } + + *os << be_uidt << "\n"; + + } + return 0; +} + +int +be_visitor_typecode_defn::gen_encapsulation (be_enum *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + + os->indent (); // start from whatever indentation level we were at + + *os << "TAO_ENCAP_BYTE_ORDER, // byte order" << be_nl; + // size of the encapsulation byte order flag. Although it is 1 byte, the + // aligned size is 4 bytes + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // generate repoID + this->gen_repoID (node); + + // generate name + os->indent (); + this->gen_name (node); + + // generate the member count + os->indent (); + *os << node->member_count () << ", // member count\n"; + // size of the member length + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // hand over to the scope to generate the typecode for elements + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::gen_encapsulation (enum) - ") + ASYS_TEXT ("cannot generate typecode for members\n")), + -1); + } + + return 0; } + +int +be_visitor_typecode_defn::gen_encapsulation (be_enum_val *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + + os->indent (); // start from whatever indentation level we were at + + // generate name + this->gen_name (node); + + return 0; +} + +int +be_visitor_typecode_defn::gen_typecode (be_exception *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + + os->indent (); // start from whatever indentation level we were at + + // check if we are repeated + const be_visitor_typecode_defn::QNode *qnode = + this->queue_lookup (this->tc_queue_, node); + if (qnode) + { + // we are repeated, so we must generate an indirection here + *os << "0xffffffff, // indirection" << be_nl; + this->tc_offset_ += sizeof (ACE_CDR::ULong); + // the offset must point to the tc_kind value of the first occurrence of + // this type + os->print ("0x%x, // negative offset (%ld)\n", + (qnode->offset - this->tc_offset_), + (qnode->offset - this->tc_offset_)); + this->tc_offset_ += sizeof (ACE_CDR::ULong); + } + else + { + if (idl_global->opt_tc () || + node->in_recursion ()) + { + if (this->queue_insert (this->tc_queue_, node, this->tc_offset_) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_typecode_defn::" + "visit_type - " + "queue insert failed\n"), + -1); + } + } + + *os << "CORBA::tk_except, // typecode kind" << be_nl; + // size of the enum + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // reset the compute queue to set the stage for computing our + // encapsulation length + this->queue_reset (this->compute_queue_); + + // emit the encapsulation length + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) - be_visitor_typecode_defn") + ASYS_TEXT ("gen_typecode (exception) - ") + ASYS_TEXT ("Failed to get encap length\n")), + -1); + } + // reset the compute queue since we must not affect computation of other + // nodes + this->queue_reset (this->compute_queue_); + + *os << this->computed_encap_len_ << ", // encapsulation length" + << be_idt << "\n"; + // size of the encap length + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // now emit the encapsulation + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::gen_typecode (exception) - ") + ASYS_TEXT ("failed to generate encapsulation\n")), + -1); + } + + *os << be_uidt << "\n"; + } + return 0; +} + +int +be_visitor_typecode_defn::gen_encapsulation (be_exception *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + + os->indent (); // start from whatever indentation level we were at + + *os << "TAO_ENCAP_BYTE_ORDER, // byte order" << be_nl; + // size of the encapsulation byte order flag. Although it is 1 byte, the + // aligned size is 4 bytes + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // generate repoID + this->gen_repoID (node); + + // generate name + os->indent (); + this->gen_name (node); + + // generate the member count + os->indent (); + *os << node->member_count () << ", // member count\n"; + // size of the member count + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // hand over to the scope to generate the typecode for elements + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::gen_encapsulation (exception) - ") + ASYS_TEXT ("cannot generate typecode for members\n")), + -1); + } + + return 0; +} + +int +be_visitor_typecode_defn::gen_encapsulation (be_field *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + be_type *bt; // our type node + + os->indent (); // start from whatever indentation level we were at + + // generate name + this->gen_name (node); + + // hand over code generation to our type node + bt = be_type::narrow_from_decl (node->field_type ()); + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED); + if (!bt || bt->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::gen_encapsulation (field) - ") + ASYS_TEXT ("failed to generate typecode\n")), + -1); + } + // revert the state to what it was before because we may be dealing with + // subsequent fields for which we have to be in the "gen scope" + // substate + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE); + return 0; +} + +int +be_visitor_typecode_defn::gen_typecode (be_interface *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + + os->indent (); // start from whatever indentation level we were at + + // check if we are repeated + const be_visitor_typecode_defn::QNode *qnode = + this->queue_lookup (this->tc_queue_, node); + if (qnode) + { + // we are repeated, so we must generate an indirection here + *os << "0xffffffff, // indirection" << be_nl; + this->tc_offset_ += sizeof (ACE_CDR::ULong); + // the offset must point to the tc_kind value of the first occurrence of + // this type + os->print ("0x%x, // negative offset (%ld)\n", + (qnode->offset - this->tc_offset_), + (qnode->offset - this->tc_offset_)); + this->tc_offset_ += sizeof (ACE_CDR::ULong); + } + else + { + if (idl_global->opt_tc () || + node->in_recursion ()) + { + if (this->queue_insert (this->tc_queue_, node, this->tc_offset_) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_typecode_defn::" + "visit_type - " + "queue insert failed\n"), + -1); + } + } + + *os << "CORBA::tk_objref, // typecode kind" << be_nl; + // size of the enum + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // reset the compute queue to set the stage for computing our + // encapsulation length + this->queue_reset (this->compute_queue_); + + // emit the encapsulation length + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) - be_visitor_typecode_defn") + ASYS_TEXT ("gen_typecode (interface) - ") + ASYS_TEXT ("Failed to get encap length\n")), + -1); + } + // reset the compute queue since we must not affect computation of other + // nodes + this->queue_reset (this->compute_queue_); + + *os << this->computed_encap_len_ << ", // encapsulation length" + << be_idt << "\n"; + // size of the encap length + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // now emit the encapsulation + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::gen_typecode (interface) - ") + ASYS_TEXT ("failed to generate encapsulation\n")), + -1); + } + *os << be_uidt << "\n"; + } + return 0; +} + +int +be_visitor_typecode_defn::gen_encapsulation (be_interface *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + + os->indent (); // start from whatever indentation level we were at + + *os << "TAO_ENCAP_BYTE_ORDER, // byte order" << be_nl; + // size of the encapsulation byte order flag. Although it is 1 byte, the + // aligned size is 4 bytes + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // generate repoID + this->gen_repoID (node); + + // generate name + os->indent (); + this->gen_name (node); + + return 0; +} + +int +be_visitor_typecode_defn::gen_typecode (be_interface_fwd *node) +{ + // nothing to do here + return 0; +} + +int +be_visitor_typecode_defn::gen_encapsulation (be_interface_fwd *node) +{ + // nothing to be done + return 0; +} + +int +be_visitor_typecode_defn::gen_typecode (be_predefined_type *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + + os->indent (); // start from the current indentation level + + // size of the enum + this->tc_offset_ += sizeof (ACE_CDR::ULong); + switch (node->pt ()) + { + case AST_PredefinedType::PT_void: + *os << "CORBA::tk_void,\n\n"; + break; + case AST_PredefinedType::PT_short: + *os << "CORBA::tk_short,\n\n"; + break; + case AST_PredefinedType::PT_ushort: + *os << "CORBA::tk_ushort,\n\n"; + break; + case AST_PredefinedType::PT_long: + *os << "CORBA::tk_long,\n\n"; + break; + case AST_PredefinedType::PT_ulong: + *os << "CORBA::tk_ulong,\n\n"; + break; + case AST_PredefinedType::PT_longlong: + *os << "CORBA::tk_longlong,\n\n"; + break; + case AST_PredefinedType::PT_ulonglong: + *os << "CORBA::tk_ulonglong,\n\n"; + break; + case AST_PredefinedType::PT_float: + *os << "CORBA::tk_float,\n\n"; + break; + case AST_PredefinedType::PT_double: + *os << "CORBA::tk_double,\n\n"; + break; + case AST_PredefinedType::PT_longdouble: + *os << "CORBA::tk_longdouble,\n\n"; + break; + case AST_PredefinedType::PT_boolean: + *os << "CORBA::tk_boolean,\n\n"; + break; + case AST_PredefinedType::PT_char: + *os << "CORBA::tk_char,\n\n"; + break; + case AST_PredefinedType::PT_octet: + *os << "CORBA::tk_octet,\n\n"; + break; + case AST_PredefinedType::PT_any: + *os << "CORBA::tk_any,\n\n"; + break; + case AST_PredefinedType::PT_wchar: + *os << "CORBA::tk_wchar,\n\n"; + break; + case AST_PredefinedType::PT_pseudo: + { + if (!ACE_OS::strcmp (node->local_name ()->get_string (), "TypeCode")) + *os << "CORBA::tk_TypeCode,\n\n"; + else + if (!ACE_OS::strcmp (node->local_name ()->get_string (), "Object")) + { + // check if we are repeated + const be_visitor_typecode_defn::QNode *qnode = + this->queue_lookup (this->tc_queue_, node); + if (qnode) + { + // we are repeated, so we must generate an indirection here + *os << "0xffffffff, // indirection" << be_nl; + this->tc_offset_ += sizeof (ACE_CDR::ULong); + // the offset must point to the tc_kind value of the first occurrence of + // this type + os->print ("0x%x, // negative offset (%ld)\n", + (qnode->offset - this->tc_offset_), + (qnode->offset - this->tc_offset_)); + this->tc_offset_ += sizeof (ACE_CDR::ULong); + } + else + { + if (idl_global->opt_tc () || + node->in_recursion ()) + { + if (this->queue_insert (this->tc_queue_, node, this->tc_offset_) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_typecode_defn::" + "visit_type - " + "queue insert failed\n"), + -1); + } + } + + *os << "CORBA::tk_objref,\n"; + + // reset the compute queue to set the stage for computing our + // encapsulation length + this->queue_reset (this->compute_queue_); + + // emit the encapsulation length + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) - be_visitor_typecode_defn") + ASYS_TEXT ("gen_typecode (predefined) - ") + ASYS_TEXT ("Failed to get encap length\n")), + -1); + } + // reset the compute queue since we must not affect + // computation of other nodes + this->queue_reset (this->compute_queue_); + + *os << this->computed_encap_len_ + << ", // encapsulation length" << be_idt << "\n"; + // size of the encap length + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // now emit the encapsulation + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::gen_typecode (predefined objref) - ") + ASYS_TEXT ("failed to generate encapsulation\n")), + -1); + } + *os << be_uidt << "\n"; + } + } + } + break; + } + return 0; +} + +int +be_visitor_typecode_defn::gen_encapsulation (be_predefined_type *node) +{ + // this one is valid only for "Object" + if (!ACE_OS::strcmp (node->local_name ()->get_string (), "Object")) + { + TAO_OutStream *os = this->ctx_->stream (); // output stream + + os->indent (); // start from whatever indentation level we were at + + *os << "TAO_ENCAP_BYTE_ORDER, // byte order" << be_nl; + // size of the encapsulation byte order flag. Although it is 1 byte, the + // aligned size is 4 bytes + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // generate repoID + this->gen_repoID (node); + + // generate name + os->indent (); + this->gen_name (node); + } + return 0; +} + +int +be_visitor_typecode_defn::gen_typecode (be_sequence *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + + os->indent (); // start from whatever indentation level we were at + + // no typecode optimization for anonymous sequences + + *os << "CORBA::tk_sequence, // typecode kind" << be_nl; + // size of the enum + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // reset the compute queue to set the stage for computing our + // encapsulation length + this->queue_reset (this->compute_queue_); + + // emit the encapsulation length + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) - be_visitor_typecode_defn") + ASYS_TEXT ("gen_typecode (sequence) - ") + ASYS_TEXT ("Failed to get encap length\n")), + -1); + } + // reset the compute queue since we must not affect computation of other + // nodes + this->queue_reset (this->compute_queue_); + + *os << this->computed_encap_len_ << ", // encapsulation length" + << be_idt << "\n"; + // size of the encap length + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // now emit the encapsulation + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::gen_typecode (sequence) - ") + ASYS_TEXT ("failed to generate encapsulation\n")), + -1); + } + *os << be_uidt << "\n"; + + return 0; +} + +int +be_visitor_typecode_defn::gen_encapsulation (be_sequence *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + be_type *bt; // base type + + os->indent (); + *os << "TAO_ENCAP_BYTE_ORDER, // byte order\n"; + // size of the encapsulation byte order flag. Although it is 1 byte, the + // aligned size is 4 bytes + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // emit typecode of element type + bt = be_type::narrow_from_decl (node->base_type ()); + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED); + if (!bt || bt->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::gen_encapsulation (sequence) - ") + ASYS_TEXT ("failed to generate typecode\n")), + -1); + } + + // emit the sequence bounds (0 if unbounded) + os->indent (); + *os << node->max_size () << ",\n"; + // size of the bound length + this->tc_offset_ += sizeof (ACE_CDR::ULong); + return 0; +} + +int +be_visitor_typecode_defn::gen_typecode (be_string *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + + // no typecode optimizations for anonymous strings + + os->indent (); // start from the current indentation level + // emit the enumeration + *os << "CORBA::tk_string, " << be_nl; + // size of the enum + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // emit the string bounds (0 if unbounded) + *os << node->max_size () << ", // string length\n"; + // size of the bounds + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + return 0; +} + +int +be_visitor_typecode_defn::gen_encapsulation (be_string *node) +{ + // nothing to be done here + return 0; +} + +int +be_visitor_typecode_defn::gen_typecode (be_structure *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + + os->indent (); // start from whatever indentation level we were at + + // check if we are repeated + const be_visitor_typecode_defn::QNode *qnode = + this->queue_lookup (this->tc_queue_, node); + if (qnode) + { + // we are repeated, so we must generate an indirection here + *os << "0xffffffff, // indirection" << be_nl; + this->tc_offset_ += sizeof (ACE_CDR::ULong); + // the offset must point to the tc_kind value of the first occurrence of + // this type + os->print ("0x%x, // negative offset (%ld)\n", + (qnode->offset - this->tc_offset_), + (qnode->offset - this->tc_offset_)); + this->tc_offset_ += sizeof (ACE_CDR::ULong); + } + else + { + if (idl_global->opt_tc () || + node->in_recursion ()) + { + if (this->queue_insert (this->tc_queue_, node, this->tc_offset_) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_typecode_defn::" + "visit_type - " + "queue insert failed\n"), + -1); + } + } + + *os << "CORBA::tk_struct, // typecode kind" << be_nl; + // size of the enum + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // reset the compute queue to set the stage for computing our + // encapsulation length + this->queue_reset (this->compute_queue_); + + // emit the encapsulation length + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) - be_visitor_typecode_defn") + ASYS_TEXT ("gen_typecode (struct) - ") + ASYS_TEXT ("Failed to get encap length\n")), + -1); + } + // reset the compute queue since we must not affect computation of other + // nodes + this->queue_reset (this->compute_queue_); + + *os << this->computed_encap_len_ << ", // encapsulation length" + << be_idt << "\n"; + // size of the encap length + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // now emit the encapsulation + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::gen_typecode (structure) - ") + ASYS_TEXT ("failed to generate encapsulation\n")), + -1); + } + *os << be_uidt << "\n"; + } + return 0; +} + +int +be_visitor_typecode_defn::gen_encapsulation (be_structure *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + + os->indent (); // start from whatever indentation level we were at + + *os << "TAO_ENCAP_BYTE_ORDER, // byte order" << be_nl; + // size of the encapsulation byte order flag. Although it is 1 byte, the + // aligned size is 4 bytes + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // generate repoID + this->gen_repoID (node); + + // generate name + os->indent (); + this->gen_name (node); + + // generate the member count + os->indent (); + *os << node->member_count () << ", // member count\n"; + // size of the member count + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // hand over to the scope to generate the typecode for elements + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE); + if (node->accept (this) == -1) + { + ACE_ERROR ((LM_ERROR, "be_structure: cannot generate typecode for members\n")); + return -1; + } + + return 0; +} + +int +be_visitor_typecode_defn::gen_typecode (be_typedef *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + + os->indent (); // start from whatever indentation level we were at + + // check if we are repeated + const be_visitor_typecode_defn::QNode *qnode = + this->queue_lookup (this->tc_queue_, node); + if (qnode) + { + // we are repeated, so we must generate an indirection here + *os << "0xffffffff, // indirection" << be_nl; + this->tc_offset_ += sizeof (ACE_CDR::ULong); + // the offset must point to the tc_kind value of the first occurrence of + // this type + os->print ("0x%x, // negative offset (%ld)\n", + (qnode->offset - this->tc_offset_), + (qnode->offset - this->tc_offset_)); + this->tc_offset_ += sizeof (ACE_CDR::ULong); + } + else + { + if (idl_global->opt_tc () || + node->in_recursion ()) + { + if (this->queue_insert (this->tc_queue_, node, this->tc_offset_) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_typecode_defn::" + "visit_type - " + "queue insert failed\n"), + -1); + } + } + + *os << "CORBA::tk_alias, // typecode kind for typedefs" << be_nl; + // size of the enum + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // reset the compute queue to set the stage for computing our + // encapsulation length + this->queue_reset (this->compute_queue_); + + // emit the encapsulation length + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) - be_visitor_typecode_defn") + ASYS_TEXT ("gen_typecode (typedef) - ") + ASYS_TEXT ("Failed to get encap length\n")), + -1); + } + // reset the compute queue since we must not affect computation of other + // nodes + this->queue_reset (this->compute_queue_); + + *os << this->computed_encap_len_ << ", // encapsulation length" + << be_idt << "\n"; + // size of the encap length + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // now emit the encapsulation + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::gen_typecode (typedef) - ") + ASYS_TEXT ("failed to generate encapsulation\n")), + -1); + } + + *os << be_uidt << "\n"; + } + return 0; +} + +int +be_visitor_typecode_defn::gen_encapsulation (be_typedef *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + be_type *bt; // base type + + os->indent (); // start from whatever indentation level we were at + + *os << "TAO_ENCAP_BYTE_ORDER, // byte order" << be_nl; + // size of the encapsulation byte order flag. Although it is 1 byte, the + // aligned size is 4 bytes + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // generate repoID + this->gen_repoID (node); + + // generate name + os->indent (); + this->gen_name (node); + + // generate typecode for the base type + bt = be_type::narrow_from_decl (node->base_type ()); + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED); + if (!bt || bt->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::gen_encapsulation (typedef) - ") + ASYS_TEXT ("failed to generate typecode\n")), + -1); + } + return 0; +} + +int +be_visitor_typecode_defn::gen_typecode (be_union *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + + os->indent (); // start from whatever indentation level we were at + + // check if we are repeated + const be_visitor_typecode_defn::QNode *qnode = + this->queue_lookup (this->tc_queue_, node); + if (qnode) + { + // we are repeated, so we must generate an indirection here + *os << "0xffffffff, // indirection" << be_nl; + this->tc_offset_ += sizeof (ACE_CDR::ULong); + // the offset must point to the tc_kind value of the first occurrence of + // this type + os->print ("0x%x, // negative offset (%ld)\n", + (qnode->offset - this->tc_offset_), + (qnode->offset - this->tc_offset_)); + this->tc_offset_ += sizeof (ACE_CDR::ULong); + } + else + { + if (idl_global->opt_tc () || + node->in_recursion ()) + { + if (this->queue_insert (this->tc_queue_, node, this->tc_offset_) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_typecode_defn::" + "visit_type - " + "queue insert failed\n"), + -1); + } + } + + *os << "CORBA::tk_union, // typecode kind" << be_nl; + // size of the enum + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // reset the compute queue to set the stage for computing our + // encapsulation length + this->queue_reset (this->compute_queue_); + + // emit the encapsulation length + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) - be_visitor_typecode_defn") + ASYS_TEXT ("gen_typecode (union) - ") + ASYS_TEXT ("Failed to get encap length\n")), + -1); + } + // reset the compute queue since we must not affect computation of other + // nodes + this->queue_reset (this->compute_queue_); + + *os << this->computed_encap_len_ << ", // encapsulation length" + << be_idt << "\n"; + // size of the encap length + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // now emit the encapsulation + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::gen_typecode (union) - ") + ASYS_TEXT ("failed to generate encapsulation\n")), + -1); + } + *os << be_uidt << "\n"; + } + return 0; +} + +int +be_visitor_typecode_defn::gen_encapsulation (be_union *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + be_type *discrim; + + os->indent (); // start from whatever indentation level we were at + + *os << "TAO_ENCAP_BYTE_ORDER, // byte order" << be_nl; + // size of the encapsulation byte order flag. Although it is 1 byte, the + // aligned size is 4 bytes + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // generate repoID + this->gen_repoID (node); + + // generate name + os->indent (); + this->gen_name (node); + + // generate typecode for discriminant + discrim = be_type::narrow_from_decl (node->disc_type ()); + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED); + if (discrim->accept (this) == -1) + { + ACE_ERROR ((LM_ERROR, "be_union: cannot generate typecode for discriminant\n")); + return -1; + } + + // generate the default used flag + os->indent (); + *os << node->default_index () << ", // default used index" << be_nl; + // size of the default index used + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // generate the member count + *os << node->member_count () << ", // member count\n"; + // size of the member count + this->tc_offset_ += sizeof (ACE_CDR::ULong); + + // hand over to the scope to generate the typecode for elements + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE); + if (node->accept (this) == -1) + { + ACE_ERROR ((LM_ERROR, "be_union: cannot generate code for members\n")); + return -1; + } + + return 0; +} + +int +be_visitor_typecode_defn::gen_encapsulation (be_union_branch *node) +{ + TAO_OutStream *os = this->ctx_->stream (); // output stream + be_type *bt; // our type node + + os->indent (); + + ACE_UINT32 buf[1]; + ACE_OS::memset (buf, 0, sizeof (buf)); + + // emit the case label value + AST_Expression *expression = node->label ()->label_val (); + AST_Expression::AST_ExprValue *ev = expression->ev (); + switch (ev->et) // the_union->udisc_type ()) + { + case AST_Expression::EV_char: + case AST_Expression::EV_bool: + os->print ("ACE_IDL_NCTOHL (0x%02.2x)", (unsigned char)ev->u.cval); + // size of bool/char aligned to 4 bytes + this->tc_offset_ += sizeof (ACE_CDR::ULong); + break; + + case AST_Expression::EV_wchar: + case AST_Expression::EV_short: + case AST_Expression::EV_ushort: + os->print ("ACE_IDL_NSTOHL (0x%04.4x)", (unsigned short)ev->u.sval); + // size of short/wchar aligned to 4 bytes + this->tc_offset_ += sizeof (ACE_CDR::ULong); + break; + + case AST_Expression::EV_ulonglong: + this->tc_offset_ += sizeof (ACE_CDR::ULong); + // continue with next case where we add aother 4 bytes + case AST_Expression::EV_long: + // size of long + this->tc_offset_ += sizeof (ACE_CDR::ULong); + *os << expression; + break; + + default: + if (expression->ec () == AST_Expression::EC_symbol) + { + // XXXASG ?? What is this case? What is its size? + *os << expression; + } + else + { + ACE_ERROR_RETURN ((LM_DEBUG, + "be_union_branch: (%N:%l) Label value " + "type (%d) is invalid\n", ev->et), -1); + } + break; + } + + *os << ", // union case label (evaluated)" << be_nl; + + // emit name + this->gen_name (node); + + // hand over code generation to our type node + bt = be_type::narrow_from_decl (node->field_type ()); + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED); + if (!bt || bt->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::gen_encapsulation (union_branch) - ") + ASYS_TEXT ("failed to generate typecode\n")), + -1); + } + + // revert the state + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE); + return 0; +} + + +// = methods for computing typecode and encapsulation sizes + +ACE_CDR::Long +be_visitor_typecode_defn::compute_tc_size (be_array *node) +{ + // 4 bytes for enumeration, 4 bytes for storing encap length val, followed by the + // actual encapsulation + + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_tc_size (array) - ") + ASYS_TEXT ("cannot compute encap len\n")), + -1); + } + + this->computed_tc_size_ = 4 + 4 + this->computed_encap_len_; + return this->computed_tc_size_; +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_encap_length (be_array *node) +{ + // Suppose "N" is the number of dimensions, then for a N dimensional array, + // we will have N encapsulations. The innermost encapsulation will hold the + // typecode of the real base type. + // Thus, we will have N byte order flags and dimensions, and N-1 tk_array + // enumerations, encapsulation lengths, and dimensions. + + be_type *bt; // base type + + bt = be_type::narrow_from_decl (node->base_type ()); + + ACE_CDR::Long encap_len = + // N byte order flags and dimensions + node->n_dims () * (4 + 4) + + + // N-1 of tk_array and that many encapsulation lengths + (node->n_dims () - 1) * (4 + 4); + + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_TC_SIZE); + if (!bt || bt->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (array) - ") + ASYS_TEXT ("cannot compute tc size for base\n")), + -1); + } + + this->computed_encap_len_ = encap_len + this->computed_tc_size_; + return this->computed_encap_len_; +} + +ACE_CDR::Long +be_visitor_typecode_defn::compute_tc_size (be_enum *node) +{ + // while computing the encapsulation length we must keep in mind the typecode + // that has gotten generated until this point. Hence, we must first check the + // "tc_queue" to ensure if are already there somewhere in a previous + // encapsulation in which case we must count only the bytes for the + // indirection. If we are not already generated, we must then check if we + // have already been counted in the current computation or not by checking + // for our presence in the compute queue. In both cases, we only include the + // 8 bytes in the computation + if (this->queue_lookup (this->tc_queue_, node) || + this->queue_lookup (this->compute_queue_, node)) + { + this->computed_tc_size_ = 4 + 4; + } + else + { + if (idl_global->opt_tc () || + node->in_recursion ()) + { + if (this->queue_insert (this->compute_queue_, node, this->tc_offset_) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_typecode_defn::" + "compute_tc_size (enum) - " + "queue insert failed\n"), + -1); + } + } + + // 4 bytes for enumeration, 4 bytes for storing encap length val, followed by the + // actual encapsulation + + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_tc_size (enum) - ") + ASYS_TEXT ("cannot compute encap len\n")), + -1); + } + + this->computed_tc_size_ = 4 + 4 + this->computed_encap_len_; + } + return this->computed_tc_size_; +} + +ACE_CDR::Long +be_visitor_typecode_defn::compute_encap_length (be_enum *node) +{ + ACE_CDR::Long encap_len; + encap_len = 4; // holds the byte order flag + + encap_len += + this->repoID_encap_len (node); // repoID storage + + // do the same thing for the local name + encap_len += this->name_encap_len (node); + + encap_len += 4; // to hold the member count + + // save the current value of scope len and start with a fresh one for our + // scope length computation + if (this->push (this->computed_scope_encap_len_) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (enum) - ") + ASYS_TEXT ("push failed\n")), + -1); + } + this->computed_scope_encap_len_ = 0; + + // compute encap length for members + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (enum) - ") + ASYS_TEXT ("cannot compute scope tc size\n")), + -1); + } + + this->computed_encap_len_ = encap_len + this->computed_scope_encap_len_; + + // pop off the previous value of computed_scope_len_ + if (this->pop (this->computed_scope_encap_len_) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (enum) - ") + ASYS_TEXT ("pop failed\n")), + -1); + } + + return this->computed_encap_len_; +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_encap_length (be_enum_val *node) +{ + this->computed_encap_len_ = this->name_encap_len (node); + return this->computed_encap_len_; +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_tc_size (be_exception *node) +{ + // while computing the encapsulation length we must keep in mind the typecode + // that has gotten generated until this point. Hence, we must first check the + // "tc_queue" to ensure if are already there somewhere in a previous + // encapsulation in which case we must count only the bytes for the + // indirection. If we are not already generated, we must then check if we + // have already been counted in the current computation or not by checking + // for our presence in the compute queue. In both cases, we only include the + // 8 bytes in the computation + if (this->queue_lookup (this->tc_queue_, node) || + this->queue_lookup (this->compute_queue_, node)) + { + this->computed_tc_size_ = 4 + 4; + } + else + { + if (idl_global->opt_tc () || + node->in_recursion ()) + { + if (this->queue_insert (this->compute_queue_, node, this->tc_offset_) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_typecode_defn::" + "compute_tc_size (exception) - " + "queue insert failed\n"), + -1); + } + } + + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_tc_size (array) - ") + ASYS_TEXT ("cannot compute encap len\n")), + -1); + } + this->computed_tc_size_ = 4 + 4 + this->computed_encap_len_; + } + return this->computed_tc_size_; +} + +ACE_CDR::Long +be_visitor_typecode_defn::compute_encap_length (be_exception *node) +{ + ACE_CDR::Long encap_len; + encap_len = 4; // holds the byte order flag + + encap_len += this->repoID_encap_len (node); // repoID + + // do the same thing for the local name + encap_len += this->name_encap_len (node); + + encap_len += 4; // to hold the member count + + // save the current value of scope len and start with a fresh one for our + // scope length computation + if (this->push (this->computed_scope_encap_len_) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (exception) - ") + ASYS_TEXT ("push failed\n")), + -1); + } + this->computed_scope_encap_len_ = 0; + + // compute encap length for members + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (exception) - ") + ASYS_TEXT ("cannot compute scope tc size\n")), + -1); + } + + this->computed_encap_len_ = encap_len + this->computed_scope_encap_len_; + + // pop off the previous value of computed_scope_len_ + if (this->pop (this->computed_scope_encap_len_) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (exception) - ") + ASYS_TEXT ("pop failed\n")), + -1); + } + + return this->computed_encap_len_; +} + +ACE_CDR::Long +be_visitor_typecode_defn::compute_encap_length (be_field *node) +{ + be_type *bt; + + // struct member is represented as the "name" followed by the typecode + + ACE_CDR::Long encap_len = + this->name_encap_len (node); // for name + + // add to this, the size of our typecode + bt = be_type::narrow_from_decl (node->field_type ()); + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_TC_SIZE); + if (!bt || bt->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (array) - ") + ASYS_TEXT ("cannot compute tc size\n")), + -1); + } + + // note that we must add typecode size of base type + this->computed_encap_len_ = encap_len + this->computed_tc_size_; + + // revert the sub state + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN); + + return this->computed_encap_len_; +} + +ACE_CDR::Long +be_visitor_typecode_defn::compute_tc_size (be_interface *node) +{ + // while computing the encapsulation length we must keep in mind the typecode + // that has gotten generated until this point. Hence, we must first check the + // "tc_queue" to ensure if are already there somewhere in a previous + // encapsulation in which case we must count only the bytes for the + // indirection. If we are not already generated, we must then check if we + // have already been counted in the current computation or not by checking + // for our presence in the compute queue. In both cases, we only include the + // 8 bytes in the computation + if (this->queue_lookup (this->tc_queue_, node) || + this->queue_lookup (this->compute_queue_, node)) + { + this->computed_tc_size_ = 4 + 4; + } + else + { + if (idl_global->opt_tc () || + node->in_recursion ()) + { + if (this->queue_insert (this->compute_queue_, node, this->tc_offset_) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_typecode_defn::" + "compute_tc_size (interface) - " + "queue insert failed\n"), + -1); + } + } + + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_tc_size (interface) - ") + ASYS_TEXT ("cannot compute encap len\n")), + -1); + } + + this->computed_tc_size_ = 4 + 4 + this->computed_encap_len_; + } + return this->computed_tc_size_; +} + +ACE_CDR::Long +be_visitor_typecode_defn::compute_encap_length (be_interface *node) +{ + this->computed_encap_len_ = 4; // holds the byte order flag + + this->computed_encap_len_ += + this->repoID_encap_len (node); // for repoID + + // do the same thing for the local name + this->computed_encap_len_ += + this->name_encap_len (node); + + return this->computed_encap_len_; +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_tc_size (be_interface_fwd *node) +{ + return 0; +} + +ACE_CDR::Long +be_visitor_typecode_defn::compute_encap_length (be_interface_fwd *node) +{ + return 0; +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_tc_size (be_predefined_type *node) +{ + if (!ACE_OS::strcmp (node->local_name ()->get_string (), + "Object")) // not same + { + // while computing the encapsulation length we must keep in mind the typecode + // that has gotten generated until this point. Hence, we must first check the + // "tc_queue" to ensure if are already there somewhere in a previous + // encapsulation in which case we must count only the bytes for the + // indirection. If we are not already generated, we must then check if we + // have already been counted in the current computation or not by checking + // for our presence in the compute queue. In both cases, we only include the + // 8 bytes in the computation + if (this->queue_lookup (this->tc_queue_, node) || + this->queue_lookup (this->compute_queue_, node)) + { + this->computed_tc_size_ = 4 + 4; + } + else + { + + if (idl_global->opt_tc () || + node->in_recursion ()) + { + if (this->queue_insert (this->compute_queue_, node, this->tc_offset_) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_typecode_defn::" + "compute_tc_size (predefined type) - " + "queue insert failed\n"), + -1); + } + } + + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_tc_size (predefined objref) - ") + ASYS_TEXT ("cannot compute encap len\n")), + -1); + } + + this->computed_tc_size_ = 4 + 4 + this->computed_encap_len_; + } + } + else + this->computed_tc_size_ = 4; + + return this->computed_tc_size_; +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_encap_length (be_predefined_type *node) +{ + if (!ACE_OS::strcmp (node->local_name ()->get_string (), + "Object")) // not same + { + this->computed_encap_len_ = 4; // holds the byte order flag + + this->computed_encap_len_ += + this->repoID_encap_len (node); // for repoID + + // do the same thing for the local name + this->computed_encap_len_ += + this->name_encap_len (node); + } + else + this->computed_encap_len_ = 0; + + return this->computed_encap_len_; +} + +ACE_CDR::Long +be_visitor_typecode_defn::compute_tc_size (be_sequence *node) +{ + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_tc_size (sequence) - ") + ASYS_TEXT ("cannot compute encap len\n")), + -1); + } + + this->computed_tc_size_ = 4 + 4 + this->computed_encap_len_; + return this->computed_tc_size_; +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_encap_length (be_sequence *node) +{ + be_type *bt; // base type + + ACE_CDR::Long encap_len = 4; // holds the byte order flag + + // add the encapsulation length of our base type + bt = be_type::narrow_from_decl (node->base_type ()); + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_TC_SIZE); + if (!bt || bt->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (sequence) - ") + ASYS_TEXT ("cannot compute tc size\n")), + -1); + } + + this->computed_encap_len_ = encap_len + this->computed_tc_size_; + this->computed_encap_len_ += 4; // to hold the max size + + return this->computed_encap_len_; +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_tc_size (be_string *node) +{ + this->computed_tc_size_ = 4 + 4; + return this->computed_tc_size_; +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_encap_length (be_string *node) +{ + this->computed_encap_len_ = 0; + return this->computed_encap_len_; +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_tc_size (be_structure *node) +{ + // while computing the encapsulation length we must keep in mind the typecode + // that has gotten generated until this point. Hence, we must first check the + // "tc_queue" to ensure if are already there somewhere in a previous + // encapsulation in which case we must count only the bytes for the + // indirection. If we are not already generated, we must then check if we + // have already been counted in the current computation or not by checking + // for our presence in the compute queue. In both cases, we only include the + // 8 bytes in the computation + if (this->queue_lookup (this->tc_queue_, node) || + this->queue_lookup (this->compute_queue_, node)) + { + this->computed_tc_size_ = 4 + 4; + } + else + { + + if (idl_global->opt_tc () || + node->in_recursion ()) + { + if (this->queue_insert (this->compute_queue_, node, this->tc_offset_) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_typecode_defn::" + "compute_tc_size (structure) - " + "queue insert failed\n"), + -1); + } + } + + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_tc_size (structure) - ") + ASYS_TEXT ("cannot compute encap len\n")), + -1); + } + + this->computed_tc_size_ = 4 + 4 + this->computed_encap_len_; + } + return this->computed_tc_size_; +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_encap_length (be_structure *node) +{ + ACE_CDR::Long encap_len = 4; // holds the byte order flag + + encap_len += this->repoID_encap_len (node); // repoID + + // do the same thing for the local name + encap_len += this->name_encap_len (node); + + encap_len += 4; // to hold the member count + + // save the current value of scope len and start with a fresh one for our + // scope length computation + if (this->push (this->computed_scope_encap_len_) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (struct) - ") + ASYS_TEXT ("push failed\n")), + -1); + } + this->computed_scope_encap_len_ = 0; + + // compute encap length for members + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (structure) - ") + ASYS_TEXT ("cannot compute scope tc size\n")), + -1); + } + + this->computed_encap_len_ = encap_len + this->computed_scope_encap_len_; + + // pop off the previous value of computed_scope_len_ + if (this->pop (this->computed_scope_encap_len_) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (struct) - ") + ASYS_TEXT ("pop failed\n")), + -1); + } + + return this->computed_encap_len_; +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_tc_size (be_typedef *node) +{ + // while computing the encapsulation length we must keep in mind the typecode + // that has gotten generated until this point. Hence, we must first check the + // "tc_queue" to ensure if are already there somewhere in a previous + // encapsulation in which case we must count only the bytes for the + // indirection. If we are not already generated, we must then check if we + // have already been counted in the current computation or not by checking + // for our presence in the compute queue. In both cases, we only include the + // 8 bytes in the computation + if (this->queue_lookup (this->tc_queue_, node) || + this->queue_lookup (this->compute_queue_, node)) + { + this->computed_tc_size_ = 4 + 4; + } + else + { + + if (idl_global->opt_tc () || + node->in_recursion ()) + { + if (this->queue_insert (this->compute_queue_, node, this->tc_offset_) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_typecode_defn::" + "compute_tc_size (typedef) - " + "queue insert failed\n"), + -1); + } + } + + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_tc_size (array) - ") + ASYS_TEXT ("cannot compute encap len\n")), + -1); + } + + this->computed_tc_size_ = 4 + 4 + this->computed_encap_len_; + } + return this->computed_tc_size_; +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_encap_length (be_typedef *node) +{ + be_type *bt; // base type + ACE_CDR::Long encap_len = 4; // holds the byte order flag + + encap_len += + this->repoID_encap_len (node); // repoID + + // do the same thing for the local name + encap_len += + this->name_encap_len (node); + + // add the encapsulation length of our base type + bt = be_type::narrow_from_decl (node->base_type ()); + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_TC_SIZE); + if (!bt || bt->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (typedef) - ") + ASYS_TEXT ("cannot compute tc size\n")), + -1); + } + + this->computed_encap_len_ = encap_len + this->computed_tc_size_; + return this->computed_encap_len_; + +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_tc_size (be_union *node) +{ + // while computing the encapsulation length we must keep in mind the typecode + // that has gotten generated until this point. Hence, we must first check the + // "tc_queue" to ensure if are already there somewhere in a previous + // encapsulation in which case we must count only the bytes for the + // indirection. If we are not already generated, we must then check if we + // have already been counted in the current computation or not by checking + // for our presence in the compute queue. In both cases, we only include the + // 8 bytes in the computation + if (this->queue_lookup (this->tc_queue_, node) || + this->queue_lookup (this->compute_queue_, node)) + { + this->computed_tc_size_ = 4 + 4; + } + else + { + if (idl_global->opt_tc () || + node->in_recursion ()) + { + if (this->queue_insert (this->compute_queue_, node, this->tc_offset_) == 0) + { + ACE_ERROR_RETURN ((LM_ERROR, + "(%N:%l) be_visitor_typecode_defn::" + "compute_tc_size (union) - " + "queue insert failed\n"), + -1); + } + } + + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_tc_size (union) - ") + ASYS_TEXT ("cannot compute encap len\n")), + -1); + } + + this->computed_tc_size_ = 4 + 4 + this->computed_encap_len_; + } + return this->computed_tc_size_; +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_encap_length (be_union *node) +{ + be_type *discrim; + + ACE_CDR::Long encap_len = 4; // holds the byte order flag + + encap_len += this->repoID_encap_len (node); // for repoID + + // do the same thing for the local name + encap_len += this->name_encap_len (node); // for name + + // add encapsulation size of discriminant typecode + discrim = be_type::narrow_from_decl (node->disc_type ()); + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_TC_SIZE); + if (!discrim || discrim->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (union) - ") + ASYS_TEXT ("cannot compute tc size\n")), + -1); + } + + encap_len += this->computed_tc_size_; + + encap_len += 4; // to hold the "default used" flag + encap_len += 4; // to hold the member count + + // save the current value of scope len and start with a fresh one for our + // scope length computation + if (this->push (this->computed_scope_encap_len_) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (union) - ") + ASYS_TEXT ("push failed\n")), + -1); + } + this->computed_scope_encap_len_ = 0; + + // compute encap length for members + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN); + if (node->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (union) - ") + ASYS_TEXT ("cannot compute scope tc size\n")), + -1); + } + + this->computed_encap_len_ = encap_len + this->computed_scope_encap_len_; + + // pop off the previous value of computed_scope_len_ + if (this->pop (this->computed_scope_encap_len_) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (union) - ") + ASYS_TEXT ("pop failed\n")), + -1); + } + + return this->computed_encap_len_; +} + + +ACE_CDR::Long +be_visitor_typecode_defn::compute_encap_length (be_union_branch *node) +{ + be_type *bt; + + ACE_CDR::Long encap_len = 4; // case label; + encap_len += + this->name_encap_len (node); // for name + + bt = be_type::narrow_from_decl (node->field_type ()); + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_TC_SIZE); + if (!bt || bt->accept (this) == -1) + { + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::compute_encap_len (union branch) - ") + ASYS_TEXT ("cannot compute tc size\n")), + -1); + } + this->computed_encap_len_ = encap_len + this->computed_tc_size_; + + this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN); + return this->computed_encap_len_; +} + +// helpers that accomplish a common task - that of generating the repository +// IDs and names in a TypeCode description + +void +be_visitor_typecode_defn::gen_repoID (be_decl *node) +{ + TAO_OutStream *os = this->ctx_->stream (); + int flag = 0; + + // check if we want to generate optimized typecodes. In such a case, there is + // no need to generate the repoID (unless we are an object reference or an + // exception in which case it is mandatory to have the repository ID) + // generate repoID + + if (idl_global->opt_tc ()) + { + switch (node->node_type ()) + { + case AST_Decl::NT_interface: + case AST_Decl::NT_interface_fwd: + case AST_Decl::NT_except: + flag = 0; + break; + case AST_Decl::NT_pre_defined: + if (!ACE_OS::strcmp (node->local_name ()->get_string (), + "Object")) + flag = 0; + else + flag = 1; + break; + default: + flag = 1; + } + } + + // XXXASG -- there is still some doubts in my mind about whether repoID + // *must* be supplied or not as per spec 2.3a. So I am not going to allow + // optimizations here. + // flag = 0; + + if (flag) + { + // optimized case + *os << "1, 0x0,"; + *os << " // repository ID = " << node->repoID (); + // size of the repoID filed + this->tc_offset_ += (2 * sizeof (ACE_CDR::ULong)); + } + else + { + // unoptimized case + *os << (ACE_OS::strlen (node->repoID ()) + 1) << ", "; + + ACE_CDR::ULong *arr, i, arrlen; + (void) this->tc_name2long (node->repoID (), arr, arrlen); + for (i = 0; i < arrlen; i++) + { + os->print ("ACE_NTOHL (0x%x), ", arr[i]); + } + *os << " // repository ID = " << node->repoID (); + // size of the repoID field + this->tc_offset_ += (arrlen + 1) * sizeof (ACE_CDR::ULong); + } + *os << "\n"; + return; +} + +void +be_visitor_typecode_defn::gen_name (be_decl *node) +{ + TAO_OutStream *os = this->ctx_->stream (); + + // generate name + if (idl_global->opt_tc ()) + { + *os << "1, 0x0,"; + *os << " // name = " << node->local_name (); + // size of the name field + this->tc_offset_ += (2 * sizeof (ACE_CDR::ULong)); + } + else + { + ACE_CDR::ULong *arr, i, arrlen; + *os << (ACE_OS::strlen (node->local_name ()->get_string ()) + 1) << ", "; + (void) this->tc_name2long (node->local_name ()->get_string (), arr, arrlen); + for (i = 0; i < arrlen; i++) + { + os->print ("ACE_NTOHL (0x%x), ", arr[i]); + } + *os << " // name = " << node->local_name (); + // size of the name field + this->tc_offset_ += (arrlen + 1) * sizeof (ACE_CDR::ULong); + } + *os << "\n"; + return; +} + +// return the length in bytes to hold the repoID inside a typecode. This +// comprises 4 bytes indicating the length of the string followed by the actual +// string represented as longs. +ACE_CDR::ULong +be_visitor_typecode_defn::repoID_encap_len (be_decl *node) +{ + int flag = 0; + + // check if we want to generate optimized typecodes. In such a case, there is + // no need to generate the repoID (unless we are an object reference or an + // exception in which case it is mandatory to have the repository ID) + // generate repoID + + if (idl_global->opt_tc ()) + { + switch (node->node_type ()) + { + case AST_Decl::NT_interface: + case AST_Decl::NT_interface_fwd: + case AST_Decl::NT_except: + flag = 0; + break; + case AST_Decl::NT_pre_defined: + if (!ACE_OS::strcmp (node->local_name ()->get_string (), + "Object")) + flag = 0; + else + flag = 1; + break; + default: + flag = 1; + } + } + + // XXXASG -- there is still some doubts in my mind about whether repoID + // *must* be supplied or not as per spec 2.3a. So I am not going to allow + // optimizations here. + //flag = 0; + + if (flag) + { + return 4 + 4; + } + else + { + ACE_CDR::ULong slen = ACE_OS::strlen (node->repoID ()) + 1; + // + 1 for NULL terminating char + + // the number of bytes to hold the string must be a multiple of 4 since this + // will be represented as an array of longs + return 4 + 4 * (slen/4 + (slen%4 ? 1:0)); + } +} + +// return the length in bytes to hold the name inside a typecode. This +// comprises 4 bytes indicating the length of the string followed by the actual +// string represented as longs. +ACE_CDR::ULong +be_visitor_typecode_defn::name_encap_len (be_decl *node) +{ + if (idl_global->opt_tc ()) + { + return 4 + 4; + } + else + { + ACE_CDR::ULong slen = + ACE_OS::strlen (node->local_name ()->get_string ()) + 1; + + // the number of bytes to hold the string must be a multiple of 4 since this + // will be represented as an array of longs + return 4 + 4 * (slen/4 + (slen%4 ? 1:0)); + } +} + +// converts a string name into an array of 4 byte longs +int +be_visitor_typecode_defn::tc_name2long (const char *name, + ACE_CDR::ULong *&larr, + ACE_CDR::ULong &arrlen) +{ + const int bytes_per_word = sizeof (ACE_CDR::ULong); + static ACE_CDR::ULong buf [NAMEBUFSIZE]; + ACE_CDR::ULong i, slen; + + slen = ACE_OS::strlen (name) + 1; // 1 for NULL terminating + + // compute the number of bytes necessary to hold the name rounded to + // the next multiple of 4 (i.e., size of long) + arrlen = slen / bytes_per_word + (slen % bytes_per_word ? 1 : 0); + + ACE_OS::memset (buf, 0, sizeof (buf)); + larr = buf; + ACE_OS::memcpy (buf, name, slen); + for (i = 0; i < arrlen; i++) + larr [i] = ACE_HTONL (larr [i]); + return 0; +} + +// post processing +int +be_visitor_typecode_defn::post_process (be_decl *node) +{ + if (this->ctx_->sub_state () == TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN) + { + this->computed_scope_encap_len_ += this->computed_encap_len_; + } + return 0; +} + +// scope stack routines +int +be_visitor_typecode_defn::push (ACE_CDR::Long val) +{ + if (this->index_ >= TAO_BE_VISITOR_TYPECODE_DEFN_MAX_STACK_SIZE) + return -1; + + this->scope_stack_ [++this->index_] = val; + return 0; +} + +int +be_visitor_typecode_defn::pop (ACE_CDR::Long &val) +{ + if (this->index_ < 0) + return -1; + + val = this->scope_stack_[this->index_--]; + return 0; +} + +const be_visitor_typecode_defn::QNode * +be_visitor_typecode_defn:: +queue_insert (ACE_Unbounded_Queue <be_visitor_typecode_defn::QNode *> &queue, + be_type *node, ACE_CDR::Long offset) +{ + be_visitor_typecode_defn::QNode *qnode; + + ACE_NEW_RETURN (qnode, be_visitor_typecode_defn::QNode, 0); + + qnode->node = node; + qnode->offset = offset; + + if (queue.enqueue_tail (qnode) == -1) + { + delete qnode; + ACE_ERROR_RETURN ((LM_ERROR, + ASYS_TEXT ("(%N:%l) be_visitor_typecode_defn") + ASYS_TEXT ("::queue_insert - failed\n")), + 0); + } + + return qnode; +} + +const be_visitor_typecode_defn::QNode * +be_visitor_typecode_defn:: +queue_lookup (ACE_Unbounded_Queue <be_visitor_typecode_defn::QNode *> &queue, + be_type *node) +{ + for (ACE_Unbounded_Queue_Iterator<be_visitor_typecode_defn::QNode *> + iter (queue); + !iter.done (); + iter.advance ()) + { + be_visitor_typecode_defn::QNode **addr, *item; + iter.next (addr); + item = *addr; + + if (!ACE_OS::strcmp (item->node->fullname (), + node->fullname ())) + { + // found + return item; + } + } + + return 0; +} + +void +be_visitor_typecode_defn:: +queue_reset (ACE_Unbounded_Queue <be_visitor_typecode_defn::QNode *> &queue) +{ + while (!queue.is_empty ()) + { + be_visitor_typecode_defn::QNode *qnode; + (void) queue.dequeue_head (qnode); + delete qnode; + } + return; +} + diff --git a/TAO/TAO_IDL/be/be_visitor_typedef/typedef_cs.cpp b/TAO/TAO_IDL/be/be_visitor_typedef/typedef_cs.cpp index 1efcfa25292..ebecde2e307 100644 --- a/TAO/TAO_IDL/be/be_visitor_typedef/typedef_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_typedef/typedef_cs.cpp @@ -130,6 +130,7 @@ be_visitor_typedef_cs::visit_typedef (be_typedef *node) be_visitor *visitor; be_visitor_context ctx (*this->ctx_); ctx.state (TAO_CodeGen::TAO_TYPECODE_DEFN); + ctx.sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE); visitor = tao_cg->make_visitor (&ctx); if (!visitor || (node->accept (visitor) == -1)) { diff --git a/TAO/TAO_IDL/be/be_visitor_union/union_cs.cpp b/TAO/TAO_IDL/be/be_visitor_union/union_cs.cpp index 6cd34f2b473..8510fc91314 100644 --- a/TAO/TAO_IDL/be/be_visitor_union/union_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_union/union_cs.cpp @@ -215,6 +215,7 @@ int be_visitor_union_cs::visit_union (be_union *node) // based on the command line options. This is still TO-DO ctx = *this->ctx_; ctx.state (TAO_CodeGen::TAO_TYPECODE_DEFN); + ctx.sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE); visitor = tao_cg->make_visitor (&ctx); if (!visitor || (node->accept (visitor) == -1)) { diff --git a/TAO/TAO_IDL/be/be_visitor_union_branch/public_access_cs.cpp b/TAO/TAO_IDL/be/be_visitor_union_branch/public_access_cs.cpp index de032dbda1c..054dcd7dadf 100644 --- a/TAO/TAO_IDL/be/be_visitor_union_branch/public_access_cs.cpp +++ b/TAO/TAO_IDL/be/be_visitor_union_branch/public_access_cs.cpp @@ -171,12 +171,20 @@ be_visitor_union_branch_public_access_cs::visit_enum (be_enum *) } int -be_visitor_union_branch_public_access_cs::visit_interface (be_interface *) +be_visitor_union_branch_public_access_cs::visit_interface (be_interface *node) { be_union_branch *ub = this->ctx_->be_node_as_union_branch (); // get union branch be_union *bu = this->ctx_->be_scope_as_union (); // get the enclosing union backend + be_type *bt; + + // check if we are visiting this node via a visit to a typedef node + if (this->ctx_->alias ()) + bt = this->ctx_->alias (); + else + bt = node; + if (!ub || !bu) { @@ -187,8 +195,10 @@ be_visitor_union_branch_public_access_cs::visit_interface (be_interface *) ), -1); } TAO_OutStream *os = this->ctx_->stream (); - *os << "return (CORBA::Object_ptr *) &this->u_." << ub->local_name () - << "_->inout ();" << be_uidt_nl; + *os << "if (alloc_flag)" << be_idt_nl; + *os << "ACE_NEW_RETURN (this->u_." << ub->local_name () << "_, " + << "TAO_Object_Field_T<" << bt->name () << ">, 0);" << be_uidt_nl; + *os << "return this->u_." << ub->local_name () << "_;" << be_uidt_nl; return 0; } diff --git a/TAO/TAO_IDL/be_include/be_array.h b/TAO/TAO_IDL/be_include/be_array.h index 4f2e6e2339d..b1f6b674bea 100644 --- a/TAO/TAO_IDL/be_include/be_array.h +++ b/TAO/TAO_IDL/be_include/be_array.h @@ -45,18 +45,6 @@ public: // generate dimensions. If slice == 1, generate dimensions for the slice // definition - virtual int gen_typecode (void); - // generate the typecode - - virtual int gen_encapsulation (void); - // encapsulation for parameters - - virtual long tc_size (void); - // return typecode size - - virtual long tc_encap_len (void); - // return length of encapsulation - // Visiting virtual int accept (be_visitor *visitor); diff --git a/TAO/TAO_IDL/be_include/be_codegen.h b/TAO/TAO_IDL/be_include/be_codegen.h index 67176507714..4b2e260b1d1 100644 --- a/TAO/TAO_IDL/be_include/be_codegen.h +++ b/TAO/TAO_IDL/be_include/be_codegen.h @@ -366,10 +366,22 @@ public: enum CG_SUB_STATE { // sub states + + // these are for the CDR operators TAO_CDR_INPUT, TAO_CDR_OUTPUT, TAO_CDR_SCOPE, + // these are for typecode generation + TAO_TC_DEFN_TYPECODE, // top level typecode + TAO_TC_DEFN_TYPECODE_NESTED, // nested tc + TAO_TC_DEFN_ENCAPSULATION, // encapsulation + TAO_TC_DEFN_SCOPE, // scope + TAO_TC_DEFN_TC_SIZE, // tc size computation + TAO_TC_DEFN_ENCAP_LEN, // encap size computation + TAO_TC_DEFN_SCOPE_LEN, // scope size computation + + // used to denote either error or don't care TAO_SUB_STATE_UNKNOWN }; diff --git a/TAO/TAO_IDL/be_include/be_decl.h b/TAO/TAO_IDL/be_include/be_decl.h index 46e64ee99df..cea43133eda 100644 --- a/TAO/TAO_IDL/be_include/be_decl.h +++ b/TAO/TAO_IDL/be_include/be_decl.h @@ -79,12 +79,6 @@ public: virtual idl_bool is_nested (void); // determines if we are inside of a nested scope or not - virtual int gen_encapsulation (void); - // encapsulation of parameters - - virtual long tc_encap_len (void); - // return length of encapsulation - virtual be_scope *scope (void); // return the scope created by this node (if one exists) @@ -147,15 +141,6 @@ protected: virtual void compute_prefix (void); // computes the prefix for the repoID - virtual int tc_name2long (const char *name, ACE_UINT32 *&, long &); - // name represented as a padded array of longs - - virtual long repoID_encap_len (void); - // return encapsulation length required to hold repository ID - - virtual long name_encap_len (void); - // return encapsulation length required to hold IDL name - // variables that indicate if the code generation for that node is already // been done. This way we avoid regenerating same code. idl_bool cli_hdr_gen_; @@ -188,9 +173,6 @@ protected: SIZE_TYPE size_type_; // whether we are fixed or variable size (by default fixed) - long encap_len_; - // encapsulation length - required for typecodes - }; #endif // if !defined diff --git a/TAO/TAO_IDL/be_include/be_enum.h b/TAO/TAO_IDL/be_include/be_enum.h index 354d155e25e..c87f73cdb60 100644 --- a/TAO/TAO_IDL/be_include/be_enum.h +++ b/TAO/TAO_IDL/be_include/be_enum.h @@ -39,18 +39,6 @@ public: be_enum (UTL_ScopedName *n, UTL_StrList *p); // constructor - virtual int gen_typecode (void); - // generate the typecode - - virtual int gen_encapsulation (void); - // encapsulation for parameters - - virtual long tc_size (void); - // return typecode size - - virtual long tc_encap_len (void); - // return length of encapsulation - virtual int member_count (void); // return the count of members diff --git a/TAO/TAO_IDL/be_include/be_enum_val.h b/TAO/TAO_IDL/be_include/be_enum_val.h index e04b9e139c9..cfde79677bf 100644 --- a/TAO/TAO_IDL/be_include/be_enum_val.h +++ b/TAO/TAO_IDL/be_include/be_enum_val.h @@ -38,12 +38,6 @@ public: be_enum_val (unsigned long v, UTL_ScopedName *n, UTL_StrList *p); // constructor - virtual int gen_encapsulation (void); - // generate the typecode - - virtual long tc_encap_len (void); - // return length of encapsulation - // Visiting virtual int accept (be_visitor *visitor); diff --git a/TAO/TAO_IDL/be_include/be_exception.h b/TAO/TAO_IDL/be_include/be_exception.h index bd24a6bbaa5..d73076c2ee5 100644 --- a/TAO/TAO_IDL/be_include/be_exception.h +++ b/TAO/TAO_IDL/be_include/be_exception.h @@ -21,21 +21,12 @@ public: // =code generation - virtual int gen_typecode (void); - // generate the typecode - - virtual int gen_encapsulation (void); - // encapsulation for parameters - - virtual long tc_size (void); - // return typecode size - - virtual long tc_encap_len (void); - // return length of encapsulation - virtual int member_count (void); // return the count of members + virtual idl_bool in_recursion (be_type *node = 0); + // check if we or the parameter node is in recursion + // Visiting virtual int accept (be_visitor *visitor); diff --git a/TAO/TAO_IDL/be_include/be_field.h b/TAO/TAO_IDL/be_include/be_field.h index d4bc99a4252..0a0de3dbffa 100644 --- a/TAO/TAO_IDL/be_include/be_field.h +++ b/TAO/TAO_IDL/be_include/be_field.h @@ -38,12 +38,6 @@ public: Visibility vis = vis_NA); // constructor - virtual int gen_encapsulation (void); - // generate the typecode - - virtual long tc_encap_len (void); - // return the total byte length of ourselves represented as an encapsulation - // Visiting virtual int accept (be_visitor *visitor); diff --git a/TAO/TAO_IDL/be_include/be_helper.h b/TAO/TAO_IDL/be_include/be_helper.h index ace81617c8b..c931b758f97 100644 --- a/TAO/TAO_IDL/be_include/be_helper.h +++ b/TAO/TAO_IDL/be_include/be_helper.h @@ -154,6 +154,21 @@ public: TAO_OutStream &operator<< (const char *str); // output the char string and return a reference to ourselves + TAO_OutStream &operator<< (const ACE_CDR::UShort num); + // output the integer and return a reference to ourselves + + TAO_OutStream &operator<< (const ACE_CDR::Short num); + // output the integer and return a reference to ourselves + + TAO_OutStream &operator<< (const ACE_CDR::ULong num); + // output the integer and return a reference to ourselves + + TAO_OutStream &operator<< (const ACE_CDR::Long num); + // output the integer and return a reference to ourselves + + TAO_OutStream &operator<< (const unsigned long num); + // output the integer and return a reference to ourselves + TAO_OutStream &operator<< (const long num); // output the integer and return a reference to ourselves diff --git a/TAO/TAO_IDL/be_include/be_interface.h b/TAO/TAO_IDL/be_include/be_interface.h index 316597e83c5..3a1cccd7baa 100644 --- a/TAO/TAO_IDL/be_include/be_interface.h +++ b/TAO/TAO_IDL/be_include/be_interface.h @@ -94,18 +94,6 @@ public: const char *local_coll_name (void) const; // retrieve the fully qualified collocated class name - virtual int gen_typecode (void); - // generate the typecode - - virtual int gen_encapsulation (void); - // encapsulation for parameters - - virtual long tc_size (void); - // return typecode size - - virtual long tc_encap_len (void); - // return length of encapsulation - virtual int traverse_inheritance_graph (tao_code_emitter gen, TAO_OutStream *os); // template method using breadth first traversal of inheritance graph diff --git a/TAO/TAO_IDL/be_include/be_interface_fwd.h b/TAO/TAO_IDL/be_include/be_interface_fwd.h index 0c40c4a6b36..4f24869a02f 100644 --- a/TAO/TAO_IDL/be_include/be_interface_fwd.h +++ b/TAO/TAO_IDL/be_include/be_interface_fwd.h @@ -56,12 +56,6 @@ public: virtual int gen_out_impl (void); // generate the _out implementation - virtual int gen_typecode (void); - // generate the typecode - - virtual long tc_size (void); - // return typecode size - // Visiting virtual int accept (be_visitor* visitor); diff --git a/TAO/TAO_IDL/be_include/be_predefined_type.h b/TAO/TAO_IDL/be_include/be_predefined_type.h index c0b2014aead..0ad44f5944f 100644 --- a/TAO/TAO_IDL/be_include/be_predefined_type.h +++ b/TAO/TAO_IDL/be_include/be_predefined_type.h @@ -44,18 +44,6 @@ public: UTL_StrList *p); // constructor - virtual int gen_typecode (void); - // generate the typecode - - virtual long tc_size (void); - // return typecode size - - virtual int gen_encapsulation (void); - // encapsulation for parameters - - virtual long tc_encap_len (void); - // return length of encapsulation - // Visiting virtual int accept (be_visitor* visitor); diff --git a/TAO/TAO_IDL/be_include/be_scope.h b/TAO/TAO_IDL/be_include/be_scope.h index f8aa25516fd..45b567587b1 100644 --- a/TAO/TAO_IDL/be_include/be_scope.h +++ b/TAO/TAO_IDL/be_include/be_scope.h @@ -46,12 +46,6 @@ public: virtual ~be_scope (void); // destructor - virtual int gen_encapsulation (void); - // encapsulation for parameters - - virtual long tc_encap_len (void); - // return length of encapsulation - virtual void comma (unsigned short set); // set the comma producing state diff --git a/TAO/TAO_IDL/be_include/be_sequence.h b/TAO/TAO_IDL/be_include/be_sequence.h index 8edeeb6ba5b..07fad27f576 100644 --- a/TAO/TAO_IDL/be_include/be_sequence.h +++ b/TAO/TAO_IDL/be_include/be_sequence.h @@ -59,18 +59,6 @@ public: // create a name for ourselves. If we are typedefed, then we get the name of // the typedef node, else we generate a name for ourselves - virtual int gen_typecode (void); - // generate the typecode - - virtual int gen_encapsulation (void); - // encapsulation for parameters - - virtual long tc_size (void); - // return typecode size - - virtual long tc_encap_len (void); - // return length of encapsulation - virtual MANAGED_TYPE managed_type (void); // return the managed type @@ -83,6 +71,9 @@ public: virtual be_decl *decl (void); // overridden method on the be_scope class + virtual idl_bool in_recursion (be_type *node = 0); + // are we or the node represented by node involved in recursion + // Visiting virtual int accept (be_visitor *visitor); diff --git a/TAO/TAO_IDL/be_include/be_string.h b/TAO/TAO_IDL/be_include/be_string.h index 771da6c5c35..a33b0196626 100644 --- a/TAO/TAO_IDL/be_include/be_string.h +++ b/TAO/TAO_IDL/be_include/be_string.h @@ -40,18 +40,6 @@ public: be_string (AST_Expression *v, long wide); // constructor - virtual int gen_typecode (void); - // generate the typecode - - virtual int gen_encapsulation (void); - // encapsulation for parameters - - virtual long tc_size (void); - // return typecode size - - virtual long tc_encap_len (void); - // return length of encapsulation - // Visiting virtual int accept (be_visitor *visitor); diff --git a/TAO/TAO_IDL/be_include/be_structure.h b/TAO/TAO_IDL/be_include/be_structure.h index 4d20ad82671..2cea9b86c6b 100644 --- a/TAO/TAO_IDL/be_include/be_structure.h +++ b/TAO/TAO_IDL/be_include/be_structure.h @@ -51,21 +51,12 @@ public: virtual int gen_out_impl (void); // generate the _out implementation - virtual int gen_typecode (void); - // generate the typecode - - virtual int gen_encapsulation (void); - // encapsulation for parameters - - virtual long tc_size (void); - // return typecode size - - virtual long tc_encap_len (void); - // return length of encapsulation - virtual int member_count (void); // return the count of members + virtual idl_bool in_recursion (be_type *node = 0); + // are we or the node represented by node involved in recursion + // Visiting virtual int accept (be_visitor *visitor); @@ -86,6 +77,7 @@ private: int member_count_; // number of members + }; #endif diff --git a/TAO/TAO_IDL/be_include/be_type.h b/TAO/TAO_IDL/be_include/be_type.h index d05d0e69015..b6dbeedf362 100644 --- a/TAO/TAO_IDL/be_include/be_type.h +++ b/TAO/TAO_IDL/be_include/be_type.h @@ -53,12 +53,6 @@ public: virtual int gen_out_impl (void); // generate the _out implementation - virtual int gen_typecode (void) = 0; - // generate the typecode description - - virtual long tc_size (void) = 0; - // return typecode size - UTL_ScopedName *tc_name (void); // return the typecode name @@ -73,6 +67,11 @@ public: // recursive simply using "base_type->node_type()" will not work, so // the most "unaliased" type is needed. + virtual idl_bool in_recursion (be_type *node = 0); + // determine if we are involved in some kind of limited recursion. Most types + // cannot be involved except structs and unions. + // If the parameter is 0, we are trying to determine this for ourselves. + // Visiting virtual int accept (be_visitor* visitor); diff --git a/TAO/TAO_IDL/be_include/be_typedef.h b/TAO/TAO_IDL/be_include/be_typedef.h index a0b8dca12c9..32befef0852 100644 --- a/TAO/TAO_IDL/be_include/be_typedef.h +++ b/TAO/TAO_IDL/be_include/be_typedef.h @@ -41,18 +41,6 @@ public: // return the most primitive base type by traversing the chain of typedefed // base types - virtual int gen_typecode (void); - // generate the typecode - - virtual int gen_encapsulation (void); - // encapsulation for parameters - - virtual long tc_size (void); - // return typecode size - - virtual long tc_encap_len (void); - // return length of encapsulation - virtual AST_Decl::NodeType base_node_type (void) const; // Return the most "unaliased" type node for the base type (see // be_type.h). diff --git a/TAO/TAO_IDL/be_include/be_union.h b/TAO/TAO_IDL/be_include/be_union.h index ee92ff75fa6..0c0541028ea 100644 --- a/TAO/TAO_IDL/be_include/be_union.h +++ b/TAO/TAO_IDL/be_include/be_union.h @@ -50,24 +50,15 @@ public: virtual int gen_out_impl (void); // generate the _out implementation - virtual int gen_typecode (void); - // generate the typecode - - virtual int gen_encapsulation (void); - // encapsulation for parameters - - virtual long tc_size (void); - // return typecode size - - virtual long tc_encap_len (void); - // return length of encapsulation - virtual int member_count (void); // return the count of members virtual int default_index (void); // return the default index used + virtual idl_bool in_recursion (be_type *node = 0); + // ar we or the parameter node involved in some kind of recursion + // Visiting virtual int accept (be_visitor *visitor); @@ -94,6 +85,7 @@ private: int default_index_; // default label index (zero based indexing) + }; #endif diff --git a/TAO/TAO_IDL/be_include/be_union_branch.h b/TAO/TAO_IDL/be_include/be_union_branch.h index e74390ca4b0..8b354afb2af 100644 --- a/TAO/TAO_IDL/be_include/be_union_branch.h +++ b/TAO/TAO_IDL/be_include/be_union_branch.h @@ -37,12 +37,6 @@ public: UTL_StrList *p); // constructor - virtual int gen_encapsulation (void); - // generate the encapsulation - - virtual long tc_encap_len (void); - // return the total byte length of ourselves represented as an encapsulation - int gen_label_value (TAO_OutStream *os); // Generate the label value (as in a switch/case statement). diff --git a/TAO/TAO_IDL/be_include/be_valuetype.h b/TAO/TAO_IDL/be_include/be_valuetype.h index 9ec3731e02d..da176b327e0 100644 --- a/TAO/TAO_IDL/be_include/be_valuetype.h +++ b/TAO/TAO_IDL/be_include/be_valuetype.h @@ -81,6 +81,7 @@ public: // retrieve the fully scoped skel class name +#if 0 virtual int gen_typecode (void); // generate the typecode @@ -92,6 +93,7 @@ public: virtual long tc_encap_len (void); // return length of encapsulation +#endif // virtual int traverse_inheritance_graph (tao_code_emitter gen, // TAO_OutStream *os); diff --git a/TAO/TAO_IDL/be_include/be_visitor_typecode.h b/TAO/TAO_IDL/be_include/be_visitor_typecode.h index 3f00ab6a94a..c6d623cf5a0 100644 --- a/TAO/TAO_IDL/be_include/be_visitor_typecode.h +++ b/TAO/TAO_IDL/be_include/be_visitor_typecode.h @@ -23,6 +23,7 @@ #define TAO_BE_VISITOR_TYPECODE_H #include "be_visitor_decl.h" +#include "be_visitor_scope.h" #include "be_visitor_typecode/typecode_decl.h" #include "be_visitor_typecode/typecode_defn.h" diff --git a/TAO/TAO_IDL/be_include/be_visitor_typecode/typecode_defn.h b/TAO/TAO_IDL/be_include/be_visitor_typecode/typecode_defn.h index e3a1765d864..e701ed72120 100644 --- a/TAO/TAO_IDL/be_include/be_visitor_typecode/typecode_defn.h +++ b/TAO/TAO_IDL/be_include/be_visitor_typecode/typecode_defn.h @@ -23,7 +23,9 @@ #ifndef _BE_VISITOR_TYPECODE_TYPECODE_DEFN_H_ #define _BE_VISITOR_TYPECODE_TYPECODE_DEFN_H_ -class be_visitor_typecode_defn : public be_visitor_decl +const int TAO_BE_VISITOR_TYPECODE_DEFN_MAX_STACK_SIZE = 1024; + +class be_visitor_typecode_defn : public be_visitor_scope { // // = TITLE @@ -57,9 +59,18 @@ public: virtual int visit_interface (be_interface *node); // visit interface + virtual int visit_interface_fwd (be_interface_fwd *node); + // visit interface + + virtual int visit_predefined_type (be_predefined_type *node); + // visit predefined types + virtual int visit_sequence (be_sequence *node); // visit a sequence + virtual int visit_string (be_string *node); + // visit a structure + virtual int visit_structure (be_structure *node); // visit a structure @@ -69,6 +80,16 @@ public: virtual int visit_union (be_union *node); // visit a union + // = visit methods for the scope elements + + virtual int visit_enum_val (be_enum_val *node); + // visit the enumeration values + + virtual int visit_field (be_field *node); + // visit the field (struct and exception member) + + virtual int visit_union_branch (be_union_branch *node); + // visit the union member // = special methods @@ -77,6 +98,189 @@ public: virtual int gen_nested_namespace_end (be_module *node); // generate the nested namespace ends + + // = methods for generating typecodes + + int gen_typecode (be_array *node); + + int gen_typecode (be_enum *node); + + int gen_typecode (be_exception *node); + + int gen_typecode (be_interface *node); + + int gen_typecode (be_interface_fwd *node); + + int gen_typecode (be_predefined_type *node); + + int gen_typecode (be_sequence *node); + + int gen_typecode (be_string *node); + + int gen_typecode (be_structure *node); + + int gen_typecode (be_typedef *node); + + int gen_typecode (be_union *node); + + // = methods to generate encapsulations for typecodes + + int gen_encapsulation (be_array *node); + + int gen_encapsulation (be_enum *node); + + int gen_encapsulation (be_enum_val *node); + + int gen_encapsulation (be_exception *node); + + int gen_encapsulation (be_field *node); + + int gen_encapsulation (be_interface *node); + + int gen_encapsulation (be_interface_fwd *node); + + int gen_encapsulation (be_predefined_type *node); + + int gen_encapsulation (be_sequence *node); + + int gen_encapsulation (be_string *node); + + int gen_encapsulation (be_structure *node); + + int gen_encapsulation (be_typedef *node); + + int gen_encapsulation (be_union *node); + + int gen_encapsulation (be_union_branch *node); + + // = methods for computing typecode sizes + + ACE_CDR::Long compute_tc_size (be_array *node); + + ACE_CDR::Long compute_tc_size (be_enum *node); + + ACE_CDR::Long compute_tc_size (be_exception *node); + + ACE_CDR::Long compute_tc_size (be_interface *node); + + ACE_CDR::Long compute_tc_size (be_interface_fwd *node); + + ACE_CDR::Long compute_tc_size (be_predefined_type *node); + + ACE_CDR::Long compute_tc_size (be_sequence *node); + + ACE_CDR::Long compute_tc_size (be_string *node); + + ACE_CDR::Long compute_tc_size (be_structure *node); + + ACE_CDR::Long compute_tc_size (be_typedef *node); + + ACE_CDR::Long compute_tc_size (be_union *node); + + // methods for computing the encapsulation length + + ACE_CDR::Long compute_encap_length (be_array *node); + + ACE_CDR::Long compute_encap_length (be_enum *node); + + ACE_CDR::Long compute_encap_length (be_enum_val *node); + + ACE_CDR::Long compute_encap_length (be_exception *node); + + ACE_CDR::Long compute_encap_length (be_field *node); + + ACE_CDR::Long compute_encap_length (be_interface *node); + + ACE_CDR::Long compute_encap_length (be_interface_fwd *node); + + ACE_CDR::Long compute_encap_length (be_predefined_type *node); + + ACE_CDR::Long compute_encap_length (be_sequence *node); + + ACE_CDR::Long compute_encap_length (be_string *node); + + ACE_CDR::Long compute_encap_length (be_structure *node); + + ACE_CDR::Long compute_encap_length (be_typedef *node); + + ACE_CDR::Long compute_encap_length (be_union *node); + + ACE_CDR::Long compute_encap_length (be_union_branch *node); + + // helpers to generate the repoID and name + + void gen_repoID (be_decl *node); + + void gen_name (be_decl *node); + + // helpers to generate encap len of the repoID and name + + ACE_CDR::ULong repoID_encap_len (be_decl *node); + + ACE_CDR::ULong name_encap_len (be_decl *node); + + // helper to get an array of long from a name + + int tc_name2long (const char *name, + ACE_CDR::ULong *&larr, + ACE_CDR::ULong &arrlen); + + // processing for scopes + + virtual int post_process (be_decl *); + // do any processing after every element except the last one of the scope is + // processed + + // data structure for handling recursive and repeated typecodes + + struct QNode + { + be_type *node; + ACE_CDR::Long offset; + }; + +private: + + ACE_CDR::Long computed_tc_size_; + // the tc size of the node under consideration + + ACE_CDR::Long computed_encap_len_; + // the encap length of the node under consideration + + ACE_CDR::Long computed_scope_encap_len_; + // the encap length of the scope of the node under consideration + + // the following are used for recursive and repeated typecodes + + ACE_CDR::Long tc_offset_; + // current computed length of the typecode + + ACE_Unbounded_Queue <QNode*> tc_queue_; + // queue to keep nodes + + ACE_Unbounded_Queue <QNode*> compute_queue_; + // queue to keep nodes + + ACE_CDR::Long scope_stack_ [TAO_BE_VISITOR_TYPECODE_DEFN_MAX_STACK_SIZE]; + // stores scope lens during computation + + // scope related routines + + int index_; + + int push (ACE_CDR::Long); + + int pop (ACE_CDR::Long &); + + // queue related routines + + const QNode *queue_insert (ACE_Unbounded_Queue <QNode*> &, + be_type *node, ACE_CDR::Long offset); + + const QNode *queue_lookup (ACE_Unbounded_Queue <QNode*> &, be_type *node); + + void queue_reset (ACE_Unbounded_Queue <QNode*> &); + }; #endif /* _BE_VISITOR_TYPECODE_TYPECODE_DEFN_H_ */ diff --git a/TAO/TAO_IDL/driver/drv_args.cpp b/TAO/TAO_IDL/driver/drv_args.cpp index 15d651de616..9f09ca74382 100644 --- a/TAO/TAO_IDL/driver/drv_args.cpp +++ b/TAO/TAO_IDL/driver/drv_args.cpp @@ -572,7 +572,7 @@ DRV_parse_args (long ac, char **av) // exception support idl_global->exception_support (1); } - else if (av[i][2] == 'o') + else if (av[i][2] == 't') { // optimized typecode support idl_global->opt_tc (1); diff --git a/TAO/docs/releasenotes/index.html b/TAO/docs/releasenotes/index.html index 16450b3a420..2e1c82cbda4 100644 --- a/TAO/docs/releasenotes/index.html +++ b/TAO/docs/releasenotes/index.html @@ -97,13 +97,18 @@ A complete list of all modifications to TAO is available in the <a href="http:// <a NAME="idl"></a>IDL Compiler</h3> Point of contact: <a href="mailto:gokhale@research.bell-labs.com">Aniruddha Gokhale</a> -<p>Current status: (As of Jan 22, 1999.) +<p>Current status: (As of May 15, 1999.) <ul> <li> Generated code closely follows the C++ Mapping specified in the latest C++ mapping for CORBA 2.3 (Document ptc/98-09-03).</li> <li> +We are now able to handle recursive types. We are also able to +generate optimized typecodes. +</li> + +<li> Struct members of type strings and arrays of strings now use the managed type instead of the _var type. This change was necessary to conform to the IDL->C++ mapping.</li> diff --git a/TAO/tao/CDR_Interpreter.cpp b/TAO/tao/CDR_Interpreter.cpp index 05f8e94c306..4fee1c6fde2 100644 --- a/TAO/tao/CDR_Interpreter.cpp +++ b/TAO/tao/CDR_Interpreter.cpp @@ -453,7 +453,7 @@ TAO_CDR_Interpreter::calc_nested_size_and_alignment (CORBA::TypeCode_ptr tc, CORBA::Long offset; if (!stream->read_long (offset) - || offset >= -8 + || offset >= -4 || ((-offset) & 0x03) != 0) { env.exception (new CORBA::BAD_TYPECODE ()); @@ -461,8 +461,15 @@ TAO_CDR_Interpreter::calc_nested_size_and_alignment (CORBA::TypeCode_ptr tc, } // Notice how we change the sign of the offset to estimate the - // maximum size. - TAO_InputCDR indirected_stream (*stream, -offset, offset); + // maximum size. + // Also note that the offset is computed starting from the offset + // field. However, by this time, we have already read the offset field i.e., + // we have already moved ahead by 4 bytes (size of CORBA::Long). So we should + // increase our offset bythis much amount. + // TAO_InputCDR indirected_stream (*stream, -1*(offset-4), offset-4); + ACE_Message_Block *mb = (ACE_Message_Block *)stream->start (); + TAO_InputCDR indirected_stream (mb->rd_ptr () + offset - 4, + -1 * (offset - 4)); // Fetch indirected-to TCKind. if (!indirected_stream.read_ulong (temp)) diff --git a/TAO/tao/Typecode.cpp b/TAO/tao/Typecode.cpp index ebff45f3a8d..2abaa4b6f2a 100644 --- a/TAO/tao/Typecode.cpp +++ b/TAO/tao/Typecode.cpp @@ -93,6 +93,8 @@ CORBA_TypeCode::CORBA_TypeCode (CORBA::TCKind kind) byte_order_ (0), kind_ (kind), parent_ (0), + tc_base_ (0), + root_tc_base_ (0), refcount_ (1), orb_owns_ (1), private_state_ (new TC_Private_State (kind)), @@ -212,6 +214,15 @@ CORBA_TypeCode::CORBA_TypeCode (CORBA::TCKind kind, // to remain dangling. Hence we save a handle to the original // allocated buffer. + // *NOTE* that the buffer parameter is simply our encapsulation. It does + // not contain our TypeCode::kind () and the length. These are passed as + // separate parameters. However, in case of indirected typecodes, the + // offset value for the indirection will effectively point to the tk_kind + // field in our CDR representation. Hence, we introduce a new field + // called tc_base_ which represents the start of our CDR + // representation. The buffer_ data member will point to our + // encapsulation. + // @@ The typecode buffer contain the encapsulation byte order // in the first byte... const CORBA::Octet *ptr = @@ -219,14 +230,27 @@ CORBA_TypeCode::CORBA_TypeCode (CORBA::TCKind kind, buffer); this->byte_order_ = *ptr; + // allocate a buffer which will accomodate our entire encapsulation plus + // 4 bytes for our tk_kind value and 4 bytes for our encapsulation + // length. The extra MAX_ALIGNMENT bytes are necessary to ensure that we + // will get a properly aligned buffer. + ACE_NEW (this->non_aligned_buffer_, - char [this->length_ + ACE_CDR::MAX_ALIGNMENT]); + char [this->length_ + 4 + 4 + ACE_CDR::MAX_ALIGNMENT]); char* start = ptr_align_binary (this->non_aligned_buffer_, ACE_CDR::MAX_ALIGNMENT); - (void) ACE_OS::memcpy (start, buffer, this->length_); - this->buffer_ = start; + (void) ACE_OS::memcpy (start, &this->kind_, 4); + (void) ACE_OS::memcpy (start + 4, &this->length_, 4); + (void) ACE_OS::memcpy (start + 8, buffer, this->length_); + // we are the topmost level typecode and hence our typecode base is + // the start whereas the buffer_ which represents the encapsulation is 8 + // bytes ahead of the typecode base + this->tc_base_ = start; + // since we do not have any parents, we are the root + this->root_tc_base_ = start; + this->buffer_ = start + 4 + 4; this->private_state_->tc_size_known_ = 1; this->private_state_->tc_size_ = size; } @@ -240,6 +264,10 @@ CORBA_TypeCode::CORBA_TypeCode (CORBA::TCKind kind, this->byte_order_ = *ptr; this->buffer_ = buffer; + // our typecode base is 8 bytes prior to our encapsulation and our root + // base is the same as that of our parent's + this->tc_base_ = this->buffer_ - 8; + this->root_tc_base_ = parent->root_tc_base_; } } diff --git a/TAO/tao/Typecode.h b/TAO/tao/Typecode.h index bc19ce58dac..9544a4cefb8 100644 --- a/TAO/tao/Typecode.h +++ b/TAO/tao/Typecode.h @@ -252,6 +252,16 @@ public: // reference to that parent to ensure its memory is not freed // inappropriately. + const char *tc_base_; + // my typecode base. Notice that the buffer_ member points to my + // encapsulation. However, for indirected typecodes, the offsets will point + // to my tk_kind field which should be pointed to be tc_base_ + + const char *root_tc_base_; + // base of the topmost level typecode. Applicable only if I have any parents, + // else it is the same as tc_base. This helps in case we have indirections + // and we need to traverse beyond encapsulation boundaries + static CORBA::Boolean skip_typecode (TAO_InputCDR &stream); // skip a typecode encoding in a given CDR stream. This is just a // helper function. diff --git a/TAO/tao/decode.cpp b/TAO/tao/decode.cpp index 0c3575a3a47..b71661ab6de 100644 --- a/TAO/tao/decode.cpp +++ b/TAO/tao/decode.cpp @@ -436,7 +436,12 @@ TAO_Marshal_TypeCode::decode (CORBA::TypeCode_ptr, // constructing indir_stream by subtracting 4 (length // of the offset parameter itself). - TAO_InputCDR indir_stream (*stream, 8, offset - 4); + // TAO_InputCDR indir_stream (*stream, 8, offset + // - 4); + ACE_Message_Block *mb = (ACE_Message_Block *)stream->start (); + TAO_InputCDR indir_stream (mb->rd_ptr () + offset - 4, + -1 * (offset - 4)); + continue_decoding = indir_stream.good_bit (); @@ -875,8 +880,21 @@ TAO_Marshal_Union::decode (CORBA::TypeCode_ptr tc, { member_val = base_union->_access (1); // marshal according to the matched typecode - return stream->decode (member_tc, member_val, - data2, env); + if (member_tc->kind () == CORBA::tk_objref) + { + // we know that the object pointer is stored in a + // TAO_Object_Field_T parametrized type + TAO_Object_Field_T<CORBA_Object>* field = + ACE_reinterpret_cast (TAO_Object_Field_T<CORBA_Object> *, + member_val); + CORBA::Object_ptr ptr = field->_upcast (); + return stream->decode (member_tc, &ptr, data2, env); + } + else + { + return stream->decode (member_tc, member_val, + data2, env); + } } } else @@ -895,7 +913,21 @@ TAO_Marshal_Union::decode (CORBA::TypeCode_ptr tc, if (default_tc) { member_val = base_union->_access (1); - return stream->decode (default_tc, member_val, data2, env); + if (default_tc->kind () == CORBA::tk_objref) + { + // we know that the object pointer is stored in a + // TAO_Object_Field_T parametrized type + TAO_Object_Field_T<CORBA_Object>* field = + ACE_reinterpret_cast (TAO_Object_Field_T<CORBA_Object> *, + member_val); + CORBA::Object_ptr ptr = field->_upcast (); + return stream->decode (default_tc, &ptr, data2, env); + } + else + { + return stream->decode (default_tc, member_val, + data2, env); + } } else return CORBA::TypeCode::TRAVERSE_CONTINUE; diff --git a/TAO/tao/encode.cpp b/TAO/tao/encode.cpp index 75fc7db7c37..ac3a0892cd3 100644 --- a/TAO/tao/encode.cpp +++ b/TAO/tao/encode.cpp @@ -565,16 +565,43 @@ TAO_Marshal_Union::encode (CORBA::TypeCode_ptr tc, { member_val = base_union->_access (0); // marshal according to the matched typecode - return stream->encode (member_tc, member_val, - data2, ACE_TRY_ENV); + + if (member_tc->kind () == CORBA::tk_objref) + { + // we know that the object pointer is stored in a + // TAO_Object_Field_T parametrized type + TAO_Object_Field_T<CORBA_Object>* field = + ACE_reinterpret_cast (TAO_Object_Field_T<CORBA_Object> *, + member_val); + CORBA::Object_ptr ptr = field->_upcast (); + return stream->encode (member_tc, &ptr, data2, ACE_TRY_ENV); + } + else + { + return stream->encode (member_tc, member_val, + data2, ACE_TRY_ENV); + } } } // we are here only if there was no match if (default_tc) { member_val = base_union->_access (0); - return stream->encode (default_tc, member_val, data2, - ACE_TRY_ENV); + if (default_tc->kind () == CORBA::tk_objref) + { + // we know that the object pointer is stored in a + // TAO_Object_Field_T parametrized type + TAO_Object_Field_T<CORBA_Object>* field = + ACE_reinterpret_cast (TAO_Object_Field_T<CORBA_Object> *, + member_val); + CORBA::Object_ptr ptr = field->_upcast (); + return stream->encode (default_tc, &ptr, data2, ACE_TRY_ENV); + } + else + { + return stream->encode (default_tc, member_val, + data2, ACE_TRY_ENV); + } } if (TAO_debug_level > 0) ACE_DEBUG ((LM_DEBUG, diff --git a/TAO/tests/Param_Test/big_union.cpp b/TAO/tests/Param_Test/big_union.cpp index 242046955c5..52bb0afc62b 100644 --- a/TAO/tests/Param_Test/big_union.cpp +++ b/TAO/tests/Param_Test/big_union.cpp @@ -278,7 +278,11 @@ Test_Big_Union::check_validity (void) if (in_array[i] != inout_array[i] || in_array[i] != out_array[i] || in_array[i] != ret_array[i]) - return 0; + { + ACE_DEBUG ((LM_DEBUG, + "mismatch of arrays\n")); + return 0; + } } } break; diff --git a/TAO/tests/Param_Test/param_test.idl b/TAO/tests/Param_Test/param_test.idl index de8c4cae069..af38dda2207 100644 --- a/TAO/tests/Param_Test/param_test.idl +++ b/TAO/tests/Param_Test/param_test.idl @@ -10,7 +10,7 @@ // // = DESCRIPTION // This IDL description is used to test all the parameter passing modes (in, -// inout, out, a0nd return) for a number of IDL data types. The goal is to +// inout, out, and return) for a number of IDL data types. The goal is to // verify the correctness of the generated stubs and skeletons, and the // the marshaling engine of TAO. // |