ifr_adding_visitor_union Class Reference

#include <ifr_adding_visitor_union.h>

Inheritance diagram for ifr_adding_visitor_union:

Inheritance graph
[legend]
Collaboration diagram for ifr_adding_visitor_union:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 ifr_adding_visitor_union (AST_Decl *scope, CORBA::Boolean is_nested)
virtual ~ifr_adding_visitor_union (void)
virtual int visit_scope (UTL_Scope *node)
virtual int visit_structure (AST_Structure *node)
virtual int visit_enum (AST_Enum *node)
virtual int visit_union (AST_Union *node)
virtual CORBA::IDLType_ptr ir_current (void) const

Private Attributes

CORBA::Boolean is_nested_
CORBA::UnionMemberSeq members_
CORBA::TypeCode_var disc_tc_
ACE_Unbounded_Queue< CORBA::Contained_ptr > move_queue_

Constructor & Destructor Documentation

ifr_adding_visitor_union::ifr_adding_visitor_union AST_Decl *  scope,
CORBA::Boolean  is_nested
 

Definition at line 21 of file ifr_adding_visitor_union.cpp.

00025   : ifr_adding_visitor (scope),
00026     is_nested_ (is_nested)
00027 {
00028 }

ifr_adding_visitor_union::~ifr_adding_visitor_union void   )  [virtual]
 

Definition at line 30 of file ifr_adding_visitor_union.cpp.

00031 {
00032 }


Member Function Documentation

CORBA::IDLType_ptr ifr_adding_visitor_union::ir_current void   )  const [virtual]
 

Definition at line 561 of file ifr_adding_visitor_union.cpp.

Referenced by visit_scope(), ifr_adding_visitor_structure::visit_union(), ifr_adding_visitor_exception::visit_union(), and ifr_adding_visitor::visit_union().

00562 {
00563   return this->ir_current_.in ();
00564 }

int ifr_adding_visitor_union::visit_enum AST_Enum *  node  )  [virtual]
 

Reimplemented from ifr_adding_visitor.

Definition at line 293 of file ifr_adding_visitor_union.cpp.

References ACE_ANY_EXCEPTION, ACE_CATCHANY, ACE_DECLARE_NEW_CORBA_ENV, ACE_ENDTRY, ACE_ENV_ARG_PARAMETER, ACE_ENV_SINGLE_ARG_PARAMETER, ACE_PRINT_EXCEPTION, ACE_TEXT(), ACE_TRY, ACE_TRY_CHECK, be_global, CORBA::is_nil(), BE_GlobalData::repository(), and CORBA::string_dup().

00294 {
00295   ACE_DECLARE_NEW_CORBA_ENV;
00296   ACE_TRY
00297     {
00298       // Is this enum already in the respository?
00299       CORBA::Contained_var prev_def =
00300         be_global->repository ()->lookup_id (node->repoID ()
00301                                              ACE_ENV_ARG_PARAMETER);
00302       ACE_TRY_CHECK;
00303 
00304       // If not, create a new entry.
00305       if (CORBA::is_nil (prev_def.in ()))
00306         {
00307           CORBA::ULong member_count = static_cast<CORBA::ULong> (node->member_count ());
00308 
00309           CORBA::EnumMemberSeq members (member_count);
00310           members.length (member_count);
00311 
00312           UTL_ScopedName *member_name = 0;
00313 
00314           // Get a list of the member names.
00315           for (CORBA::ULong i = 0; i < member_count; ++i)
00316             {
00317               member_name = node->value_to_name (i);
00318 
00319               members[i] =
00320                 CORBA::string_dup (member_name->last_component ()->get_string ());
00321             }
00322 
00323           this->ir_current_ =
00324             be_global->repository ()->create_enum (
00325                                           node->repoID (),
00326                                           node->local_name ()->get_string (),
00327                                           node->version (),
00328                                           members
00329                                           ACE_ENV_ARG_PARAMETER
00330                                         );
00331           ACE_TRY_CHECK;
00332 
00333           CORBA::Contained_ptr tmp =
00334             CORBA::Contained::_narrow (this->ir_current_.in ()
00335                                       ACE_ENV_ARG_PARAMETER);
00336           ACE_TRY_CHECK;
00337 
00338           // Since the enclosing UnionDef hasn't been created
00339           // yet, we don't have a scope, so this nested EnumDef
00340           // (which was created at global scope) goes on the
00341           // queue to be moved later.
00342           this->move_queue_.enqueue_tail (tmp);
00343 
00344           node->ifr_added (1);
00345         }
00346       else
00347         {
00348           // If the line below is true, we are clobbering a previous
00349           // entry (from another IDL file) of another type. In that
00350           // case we do what other ORB vendors do, and destroy the
00351           // original entry, create the new one, and let the user beware.
00352           if (node->ifr_added () == 0)
00353             {
00354               prev_def->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00355               ACE_TRY_CHECK;
00356 
00357               // This call will take the other branch.
00358               return this->visit_enum (node);
00359             }
00360 
00361           this->ir_current_ =
00362             CORBA::IDLType::_narrow (prev_def.in ()
00363                                     ACE_ENV_ARG_PARAMETER);
00364           ACE_TRY_CHECK;
00365         }
00366     }
00367   ACE_CATCHANY
00368     {
00369       ACE_PRINT_EXCEPTION (
00370           ACE_ANY_EXCEPTION,
00371           ACE_TEXT ("ifr_adding_visitor_union::visit_enum")
00372         );
00373 
00374       return -1;
00375     }
00376   ACE_ENDTRY;
00377 
00378   return 0;
00379 }

int ifr_adding_visitor_union::visit_scope UTL_Scope *  node  )  [virtual]
 

Reimplemented from ifr_adding_visitor.

Definition at line 36 of file ifr_adding_visitor_union.cpp.

References ACE_ANY_EXCEPTION, ACE_CATCHANY, ACE_DECLARE_NEW_CORBA_ENV, ACE_ENDTRY, ACE_ENV_ARG_PARAMETER, ACE_ERROR_RETURN, ACE_NEW_RETURN, ACE_PRINT_EXCEPTION, ACE_TEXT(), ACE_TRY, ACE_TRY_CHECK, ifr_adding_visitor::get_referenced_type(), ir_current(), LM_ERROR, ifr_adding_visitor::load_any(), CORBA::string_dup(), ifr_adding_visitor::visit_scope(), and ACE_OutputCDR::write_ulong().

Referenced by visit_union().

00037 {
00038   // If the union has members that are scopes but not unions,
00039   // the regular visit_scope method should be called instead.
00040   if (node->scope_node_type () != AST_Decl::NT_union)
00041     {
00042       return ifr_adding_visitor::visit_scope (node);
00043     }
00044 
00045   AST_Union *u = AST_Union::narrow_from_scope (node);
00046 
00047   CORBA::ULong nfields = static_cast<CORBA::ULong> (u->nfields ());
00048 
00049   this->members_.length (nfields);
00050 
00051   AST_Field **f = 0;
00052 
00053   // Index into members_.
00054   CORBA::ULong index = 0;
00055 
00056   ACE_DECLARE_NEW_CORBA_ENV;
00057   ACE_TRY
00058     {
00059       // Visit each field.
00060       for (CORBA::ULong i = 0; i < nfields; ++i)
00061         {
00062           if (u->field (f, i) != 0)
00063             {
00064               ACE_ERROR_RETURN ((
00065                   LM_ERROR,
00066                   ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
00067                   ACE_TEXT ("visit_scope -")
00068                   ACE_TEXT (" field node access failed\n")
00069                 ),
00070                 -1
00071               );
00072             }
00073 
00074           AST_Type *ft = (*f)->field_type ();
00075 
00076           bool defined_here = ft->is_child (this->scope_);
00077 
00078           // If the union member is defined in the union, we have to
00079           // do some visiting - otherwise we can just look up the entry.
00080           if (defined_here)
00081             {
00082               if (ft->node_type () == AST_Decl::NT_union)
00083                 {
00084                   // Since the enclosing scope hasn't been created yet,
00085                   // we make a special visitor to create this member
00086                   // at global scope and move it into the union later.
00087                   ifr_adding_visitor_union visitor (ft,
00088                                                     1);
00089 
00090                   if (ft->ast_accept (&visitor) == -1)
00091                     {
00092                       ACE_ERROR_RETURN ((
00093                           LM_ERROR,
00094                           ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
00095                           ACE_TEXT ("visit_scope -")
00096                           ACE_TEXT (" failed to accept visitor\n")
00097                         ),
00098                         -1
00099                       );
00100                     }
00101 
00102                   this->ir_current_ =
00103                     CORBA::IDLType::_duplicate (visitor.ir_current ());
00104 
00105                   CORBA::Contained_ptr tmp =
00106                     CORBA::Contained::_narrow (visitor.ir_current ()
00107                                               ACE_ENV_ARG_PARAMETER);
00108                   ACE_TRY_CHECK;
00109 
00110                   this->move_queue_.enqueue_tail (tmp);
00111                 }
00112               else
00113                 {
00114                   if (ft->ast_accept (this) == -1)
00115                     {
00116                       ACE_ERROR_RETURN ((
00117                           LM_ERROR,
00118                           ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
00119                           ACE_TEXT ("visit_scope -")
00120                           ACE_TEXT (" failed to accept visitor\n")
00121                         ),
00122                         -1
00123                       );
00124                     }
00125                 }
00126             }
00127           else
00128             {
00129               // Updates ir_current_.
00130               this->get_referenced_type (ft
00131                                          ACE_ENV_ARG_PARAMETER);
00132               ACE_TRY_CHECK;
00133             }
00134 
00135           // Get the case label(s).
00136 
00137           AST_UnionBranch *ub = 0;
00138           AST_UnionLabel *case_label = 0;
00139 
00140           ub = AST_UnionBranch::narrow_from_decl (*f);
00141 
00142           unsigned long len = ub->label_list_length ();
00143 
00144           // If there are multiple case labels, we will have an element
00145           // in the UnionMemberSeq for each label, not just for each member,
00146           // so the list length and the loop terminator must both be
00147           // increased accordingly.
00148           if (len > 1)
00149             {
00150               this->members_.length (this->members_.length () + len - 1);
00151             }
00152 
00153           for (unsigned long j = 0; j < len; ++j)
00154             {
00155               case_label = ub->label (j);
00156 
00157               // Is this a regular label or default label?
00158               if (case_label->label_kind () == AST_UnionLabel::UL_label)
00159                 {
00160                   AST_Expression::AST_ExprValue *ev =
00161                     case_label->label_val ()->ev ();
00162 
00163                   // If the discriminator is an enum, we can't just insert
00164                   // a ulong into the Any member of struct UnionMember.
00165                   if (u->disc_type ()->node_type () == AST_Decl::NT_enum)
00166                     {
00167                       TAO_OutputCDR cdr;
00168                       cdr.write_ulong (ev->u.ulval);
00169                       TAO_InputCDR in_cdr (cdr);
00170                       TAO::Unknown_IDL_Type *unk = 0;
00171                       ACE_NEW_RETURN (unk,
00172                                       TAO::Unknown_IDL_Type (
00173                                           this->disc_tc_.in (),
00174                                           in_cdr
00175                                         ),
00176                                       -1);
00177                       this->members_[index].label.replace (unk);
00178                     }
00179                   else
00180                     {
00181                       this->load_any (ev,
00182                                       this->members_[index].label);
00183                     }
00184                 }
00185               else      // Default case label.
00186                 {
00187                   this->members_[index].label <<= CORBA::Any::from_octet (0);
00188                 }
00189 
00190               this->members_[index].name =
00191                 CORBA::string_dup ((*f)->local_name ()->get_string ());
00192 
00193               // IfR method create_union does not use this - it just needs
00194               // to be non-zero for marshaling.
00195               this->members_[index].type =
00196                 CORBA::TypeCode::_duplicate (CORBA::_tc_void);
00197 
00198               this->members_[index++].type_def =
00199                 CORBA::IDLType::_duplicate (this->ir_current_.in ());
00200             }
00201         }
00202     }
00203   ACE_CATCHANY
00204     {
00205       ACE_PRINT_EXCEPTION (
00206           ACE_ANY_EXCEPTION,
00207           ACE_TEXT ("ifr_adding_visitor_union::visit_scope")
00208         );
00209 
00210       return -1;
00211     }
00212   ACE_ENDTRY;
00213 
00214   return 0;
00215 }

int ifr_adding_visitor_union::visit_structure AST_Structure *  node  )  [virtual]
 

Reimplemented from ifr_adding_visitor.

Definition at line 218 of file ifr_adding_visitor_union.cpp.

References ACE_ANY_EXCEPTION, ACE_CATCHANY, ACE_DECLARE_NEW_CORBA_ENV, ACE_ENDTRY, ACE_ENV_ARG_PARAMETER, ACE_ENV_SINGLE_ARG_PARAMETER, ACE_PRINT_EXCEPTION, ACE_TEXT(), ACE_TRY, ACE_TRY_CHECK, be_global, ifr_adding_visitor_structure::ir_current(), CORBA::is_nil(), BE_GlobalData::repository(), and ifr_adding_visitor_structure::visit_structure().

00219 {
00220   ACE_DECLARE_NEW_CORBA_ENV;
00221   ACE_TRY
00222     {
00223       // Is this struct already in the respository?
00224       CORBA::Contained_var prev_def =
00225         be_global->repository ()->lookup_id (node->repoID ()
00226                                              ACE_ENV_ARG_PARAMETER);
00227       ACE_TRY_CHECK;
00228 
00229       // If not, create a new entry.
00230       if (CORBA::is_nil (prev_def.in ()))
00231         {
00232           ifr_adding_visitor_structure visitor (node,
00233                                                 1);
00234 
00235           int retval = visitor.visit_structure (node);
00236 
00237           if (retval == 0)
00238             {
00239               // Get the result of the visit.
00240               this->ir_current_ =
00241                 CORBA::IDLType::_duplicate (visitor.ir_current ());
00242 
00243               CORBA::Contained_ptr tmp =
00244                 CORBA::Contained::_narrow (visitor.ir_current ()
00245                                           ACE_ENV_ARG_PARAMETER);
00246               ACE_TRY_CHECK;
00247 
00248               // Since the enclosing UnionDef hasn't been created
00249               // yet, we don't have a scope, so this nested StructDef
00250               // (which was created at global scope) goes on the
00251               // queue to be moved later.
00252               this->move_queue_.enqueue_tail (tmp);
00253             }
00254 
00255           return retval;
00256         }
00257       else
00258         {
00259           // If the line below is true, we are clobbering a previous
00260           // entry (from another IDL file) of another type. In that
00261           // case we do what other ORB vendors do, and destroy the
00262           // original entry, create the new one, and let the user beware.
00263           if (node->ifr_added () == 0)
00264             {
00265               prev_def->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00266               ACE_TRY_CHECK;
00267 
00268               // This call will take the other branch.
00269               return this->visit_structure (node);
00270             }
00271 
00272           this->ir_current_ =
00273             CORBA::IDLType::_narrow (prev_def.in ()
00274                                     ACE_ENV_ARG_PARAMETER);
00275           ACE_TRY_CHECK;
00276         }
00277     }
00278   ACE_CATCHANY
00279     {
00280       ACE_PRINT_EXCEPTION (
00281           ACE_ANY_EXCEPTION,
00282           ACE_TEXT ("ifr_adding_visitor_union::visit_structure")
00283         );
00284 
00285       return -1;
00286     }
00287   ACE_ENDTRY;
00288 
00289   return 0;
00290 }

int ifr_adding_visitor_union::visit_union AST_Union *  node  )  [virtual]
 

Reimplemented from ifr_adding_visitor.

Definition at line 382 of file ifr_adding_visitor_union.cpp.

References ACE_ANY_EXCEPTION, ACE_CATCHANY, ACE_DECLARE_NEW_CORBA_ENV, ACE_ENDTRY, ACE_ENV_ARG_PARAMETER, ACE_ENV_SINGLE_ARG_PARAMETER, ACE_ERROR_RETURN, ACE_PRINT_EXCEPTION, ACE_TEXT(), ACE_TRY, ACE_TRY_CHECK, be_global, disc_tc_, BE_GlobalData::holding_scope(), BE_GlobalData::ifr_scopes(), CORBA::is_nil(), LM_ERROR, BE_GlobalData::repository(), and visit_scope().

Referenced by ifr_adding_visitor_structure::visit_union(), ifr_adding_visitor_exception::visit_union(), and ifr_adding_visitor::visit_union().

00383 {
00384   ACE_DECLARE_NEW_CORBA_ENV;
00385   ACE_TRY
00386     {
00387       CORBA::Contained_var prev_def =
00388         be_global->repository ()->lookup_id (node->repoID ()
00389                                              ACE_ENV_ARG_PARAMETER);
00390       ACE_TRY_CHECK;
00391 
00392       if (CORBA::is_nil (prev_def.in ()))
00393         {
00394           // Get the discrimintor node.
00395           AST_ConcreteType *disc_type = node->disc_type ();
00396 
00397           // Since the IDL compiler stores enum label values as ulongs,
00398           // we need to get the typecode to insert the label value into
00399           // an Any.
00400           if (disc_type->node_type () == AST_Decl::NT_enum)
00401             {
00402               CORBA::Contained_var disc_def =
00403                 be_global->repository ()->lookup_id (disc_type->repoID ()
00404                                                      ACE_ENV_ARG_PARAMETER);
00405               ACE_TRY_CHECK;
00406 
00407               if (CORBA::is_nil (disc_def.in ()))
00408                 {
00409                   ACE_ERROR_RETURN ((
00410                       LM_ERROR,
00411                       ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
00412                       ACE_TEXT ("visit_union -")
00413                       ACE_TEXT (" discriminator not found in repository\n")
00414                     ),
00415                     -1
00416                   );
00417                 }
00418 
00419               CORBA::IDLType_var idl_def =
00420                 CORBA::IDLType::_narrow (disc_def.in ()
00421                                         ACE_ENV_ARG_PARAMETER);
00422               ACE_TRY_CHECK;
00423 
00424               this->disc_tc_ = idl_def->type (ACE_ENV_SINGLE_ARG_PARAMETER);
00425               ACE_TRY_CHECK;
00426             }
00427 
00428           if (this->visit_scope (node) == -1)
00429             {
00430               ACE_ERROR_RETURN ((
00431                   LM_ERROR,
00432                   ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::visit_union -")
00433                   ACE_TEXT (" visit_scope failed\n")
00434                 ),
00435                 -1
00436               );
00437             }
00438 
00439           // This will put an IR object for the discriminator in ir_current_.
00440           if (disc_type->ast_accept (this) == -1)
00441             {
00442               ACE_ERROR_RETURN ((
00443                   LM_ERROR,
00444                   ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::visit_union -")
00445                   ACE_TEXT (" failed to accept visitor\n")
00446                 ),
00447                 -1
00448               );
00449             }
00450 
00451           if (this->is_nested_)
00452             {
00453               this->ir_current_ =
00454                 be_global->holding_scope ()->create_union (
00455                     node->repoID (),
00456                     node->local_name ()->get_string (),
00457                     node->version (),
00458                     this->ir_current_.in (),
00459                     this->members_
00460                     ACE_ENV_ARG_PARAMETER
00461                   );
00462             }
00463           else
00464             {
00465               CORBA::Container_ptr current_scope =
00466                 CORBA::Container::_nil ();
00467 
00468               if (be_global->ifr_scopes ().top (current_scope) != 0)
00469                 {
00470                   ACE_ERROR_RETURN ((
00471                       LM_ERROR,
00472                       ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
00473                       ACE_TEXT ("visit_union -")
00474                       ACE_TEXT (" scope stack is empty\n")
00475                     ),
00476                     -1
00477                   );
00478                 }
00479 
00480               this->ir_current_ =
00481                 current_scope->create_union (
00482                                    node->repoID (),
00483                                    node->local_name ()->get_string (),
00484                                    node->version (),
00485                                    this->ir_current_.in (),
00486                                    this->members_
00487                                    ACE_ENV_ARG_PARAMETER
00488                                 );
00489             }
00490 
00491           ACE_TRY_CHECK;
00492 
00493           size_t size = this->move_queue_.size ();
00494 
00495           if (size > 0)
00496             {
00497               CORBA::Contained_var traveller;
00498 
00499               CORBA::Container_var new_container =
00500                 CORBA::Container::_narrow (this->ir_current_.in ()
00501                                           ACE_ENV_ARG_PARAMETER);
00502               ACE_TRY_CHECK;
00503 
00504               for (size_t i = 0; i < size; ++i)
00505                 {
00506                   this->move_queue_.dequeue_head (traveller);
00507 
00508                   CORBA::String_var name = traveller->name (ACE_ENV_SINGLE_ARG_PARAMETER);
00509                   ACE_TRY_CHECK;
00510 
00511                   CORBA::String_var version =
00512                     traveller->version (ACE_ENV_SINGLE_ARG_PARAMETER);
00513                   ACE_TRY_CHECK;
00514 
00515                   traveller->move (new_container.in (),
00516                                    name.in (),
00517                                    version.in ()
00518                                    ACE_ENV_ARG_PARAMETER);
00519                   ACE_TRY_CHECK;
00520                 }
00521             }
00522 
00523           node->ifr_added (1);
00524         } // if (CORBA::is_nil (...))
00525       else
00526         {
00527           // If the line below is true, we are clobbering a previous
00528           // entry (from another IDL file) of another type. In that
00529           // case we do what other ORB vendors do, and destroy the
00530           // original entry, create the new one, and let the user beware.
00531           if (node->ifr_added () == 0)
00532             {
00533               prev_def->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
00534               ACE_TRY_CHECK;
00535 
00536               // This call will take the other branch.
00537               return this->visit_union (node);
00538             }
00539 
00540           this->ir_current_ =
00541             CORBA::IDLType::_narrow (prev_def.in ()
00542                                     ACE_ENV_ARG_PARAMETER);
00543           ACE_TRY_CHECK;
00544         }
00545     }
00546   ACE_CATCHANY
00547     {
00548       ACE_PRINT_EXCEPTION (
00549           ACE_ANY_EXCEPTION,
00550           ACE_TEXT ("ifr_adding_visitor_union::visit_union")
00551         );
00552 
00553       return -1;
00554     }
00555   ACE_ENDTRY;
00556 
00557   return 0;
00558 }


Member Data Documentation

CORBA::TypeCode_var ifr_adding_visitor_union::disc_tc_ [private]
 

Definition at line 71 of file ifr_adding_visitor_union.h.

Referenced by visit_union().

CORBA::Boolean ifr_adding_visitor_union::is_nested_ [private]
 

Definition at line 63 of file ifr_adding_visitor_union.h.

CORBA::UnionMemberSeq ifr_adding_visitor_union::members_ [private]
 

Definition at line 67 of file ifr_adding_visitor_union.h.

ACE_Unbounded_Queue<CORBA::Contained_ptr> ifr_adding_visitor_union::move_queue_ [private]
 

Definition at line 76 of file ifr_adding_visitor_union.h.


The documentation for this class was generated from the following files:
Generated on Thu Nov 9 14:12:20 2006 for TAO_IFR by doxygen 1.3.6