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, bool 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 Member Functions

int add_members (AST_Union *node, CORBA::UnionDef_ptr union_def)

Private Attributes

bool 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,
bool  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

int ifr_adding_visitor_union::add_members AST_Union *  node,
CORBA::UnionDef_ptr  union_def
[private]
 

Definition at line 476 of file ifr_adding_visitor_union.cpp.

References ACE_ERROR_RETURN, ACE_TEXT(), LM_ERROR, and visit_scope().

Referenced by visit_union().

00478 {
00479   if (this->visit_scope (node) == -1)
00480     {
00481       ACE_ERROR_RETURN ((
00482           LM_ERROR,
00483           ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::visit_union -")
00484           ACE_TEXT (" visit_scope failed\n")
00485         ),
00486         -1
00487       );
00488     }
00489 
00490   // Correct ir_current_ and move the real union members into the union.
00491   this->ir_current_= CORBA::UnionDef::_duplicate (union_def);
00492   union_def->members (this->members_);
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 
00502       for (size_t i = 0; i < size; ++i)
00503         {
00504           this->move_queue_.dequeue_head (traveller);
00505 
00506           CORBA::String_var name = traveller->name ();
00507           CORBA::String_var version = traveller->version ();
00508 
00509           traveller->move (new_container.in (),
00510                            name.in (),
00511                            version.in ());
00512         }
00513     }
00514    
00515   node->ifr_added (true);
00516   return 0;
00517 }

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

Definition at line 470 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().

00471 {
00472   return this->ir_current_.in ();
00473 }

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

Reimplemented from ifr_adding_visitor.

Definition at line 272 of file ifr_adding_visitor_union.cpp.

References ACE_TEXT(), be_global, CORBA::is_nil(), BE_GlobalData::repository(), and CORBA::string_dup().

00273 {
00274   try
00275     {
00276       // Is this enum already in the respository?
00277       CORBA::Contained_var prev_def =
00278         be_global->repository ()->lookup_id (node->repoID ());
00279 
00280       // If not, create a new entry.
00281       if (CORBA::is_nil (prev_def.in ()))
00282         {
00283           CORBA::ULong member_count = static_cast<CORBA::ULong> (node->member_count ());
00284 
00285           CORBA::EnumMemberSeq members (member_count);
00286           members.length (member_count);
00287 
00288           UTL_ScopedName *member_name = 0;
00289 
00290           // Get a list of the member names.
00291           for (CORBA::ULong i = 0; i < member_count; ++i)
00292             {
00293               member_name = node->value_to_name (i);
00294 
00295               members[i] =
00296                 CORBA::string_dup (member_name->last_component ()->get_string ());
00297             }
00298 
00299           this->ir_current_ =
00300             be_global->repository ()->create_enum (
00301                                           node->repoID (),
00302                                           node->local_name ()->get_string (),
00303                                           node->version (),
00304                                           members
00305                                         );
00306 
00307           CORBA::Contained_ptr tmp =
00308             CORBA::Contained::_narrow (this->ir_current_.in ());
00309 
00310           // Since the enclosing UnionDef hasn't been created
00311           // yet, we don't have a scope, so this nested EnumDef
00312           // (which was created at global scope) goes on the
00313           // queue to be moved later.
00314           this->move_queue_.enqueue_tail (tmp);
00315 
00316           node->ifr_added (true);
00317         }
00318       else
00319         {
00320           // If the line below is true, we are clobbering a previous
00321           // entry (from another IDL file) of another type. In that
00322           // case we do what other ORB vendors do, and destroy the
00323           // original entry, create the new one, and let the user beware.
00324           if (!node->ifr_added ())
00325             {
00326               prev_def->destroy ();
00327 
00328               // This call will take the other branch.
00329               return this->visit_enum (node);
00330             }
00331 
00332           this->ir_current_ =
00333             CORBA::IDLType::_narrow (prev_def.in ());
00334         }
00335     }
00336   catch (const CORBA::Exception& ex)
00337     {
00338       ex._tao_print_exception (
00339         ACE_TEXT (
00340           "ifr_adding_visitor_union::visit_enum"));
00341 
00342       return -1;
00343     }
00344 
00345   return 0;
00346 }

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_ERROR_RETURN, ACE_NEW_RETURN, ACE_TEXT(), 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 add_members().

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

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

Reimplemented from ifr_adding_visitor.

Definition at line 207 of file ifr_adding_visitor_union.cpp.

References ACE_TEXT(), be_global, ifr_adding_visitor_structure::ir_current(), CORBA::is_nil(), BE_GlobalData::repository(), and ifr_adding_visitor_structure::visit_structure().

00208 {
00209   try
00210     {
00211       // Is this struct already in the respository?
00212       CORBA::Contained_var prev_def =
00213         be_global->repository ()->lookup_id (node->repoID ());
00214 
00215       // If not, create a new entry.
00216       if (CORBA::is_nil (prev_def.in ()))
00217         {
00218           ifr_adding_visitor_structure visitor (node,
00219                                                 1);
00220 
00221           int retval = visitor.visit_structure (node);
00222 
00223           if (retval == 0)
00224             {
00225               // Get the result of the visit.
00226               this->ir_current_ =
00227                 CORBA::IDLType::_duplicate (visitor.ir_current ());
00228 
00229               CORBA::Contained_ptr tmp =
00230                 CORBA::Contained::_narrow (visitor.ir_current ());
00231 
00232               // Since the enclosing UnionDef hasn't been created
00233               // yet, we don't have a scope, so this nested StructDef
00234               // (which was created at global scope) goes on the
00235               // queue to be moved later.
00236               this->move_queue_.enqueue_tail (tmp);
00237             }
00238 
00239           return retval;
00240         }
00241       else
00242         {
00243           // If the line below is true, we are clobbering a previous
00244           // entry (from another IDL file) of another type. In that
00245           // case we do what other ORB vendors do, and destroy the
00246           // original entry, create the new one, and let the user beware.
00247           if (!node->ifr_added ())
00248             {
00249               prev_def->destroy ();
00250 
00251               // This call will take the other branch.
00252               return this->visit_structure (node);
00253             }
00254 
00255           this->ir_current_ =
00256             CORBA::IDLType::_narrow (prev_def.in ());
00257         }
00258     }
00259   catch (const CORBA::Exception& ex)
00260     {
00261       ex._tao_print_exception (
00262         ACE_TEXT (
00263           "ifr_adding_visitor_union::visit_structure"));
00264 
00265       return -1;
00266     }
00267 
00268   return 0;
00269 }

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

Reimplemented from ifr_adding_visitor.

Definition at line 349 of file ifr_adding_visitor_union.cpp.

References ACE_ERROR_RETURN, ACE_TEXT(), add_members(), be_global, disc_tc_, BE_GlobalData::holding_scope(), BE_GlobalData::ifr_scopes(), CORBA::is_nil(), LM_ERROR, and BE_GlobalData::repository().

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

00350 {
00351   try
00352     {
00353       // This will put the discriminator in ir_current_.
00354       if (node->disc_type ()->ast_accept (this) == -1)
00355         {
00356           ACE_ERROR_RETURN ((
00357               LM_ERROR,
00358               ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
00359               ACE_TEXT ("visit_union -")
00360               ACE_TEXT (" visit of discriminator failed\n")
00361             ),
00362             -1
00363           );
00364         }
00365 
00366       this->disc_tc_ = this->ir_current_->type ();
00367 
00368       CORBA::UnionDef_var union_def;
00369       CORBA::Contained_var prev_def =
00370         be_global->repository ()->lookup_id (node->repoID ());
00371 
00372       if (CORBA::is_nil (prev_def.in ()))
00373         {
00374           CORBA::UnionMemberSeq dummyMembers;
00375           dummyMembers.length (0);
00376           CORBA::Container_ptr current_scope = CORBA::Container::_nil ();
00377           
00378           if (this->is_nested_)
00379             {
00380               current_scope = be_global->holding_scope ();
00381             }
00382           else if (be_global->ifr_scopes ().top (current_scope) != 0)
00383             {
00384               ACE_ERROR_RETURN ((
00385                   LM_ERROR,
00386                   ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
00387                   ACE_TEXT ("visit_union -")
00388                   ACE_TEXT (" scope stack is empty\n")
00389                 ),
00390                 -1
00391               );
00392             }
00393             
00394           // First create the named union without any members.
00395           union_def =
00396             current_scope->create_union (
00397                 node->repoID (),
00398                 node->local_name ()->get_string (),
00399                 node->version (),
00400                 this->ir_current_.in (),
00401                 this->members_
00402               );
00403          
00404           // Then add the real union members (which corrupts ir_current_).
00405           if (this->add_members (node, union_def.in ()) == -1)
00406             {
00407               ACE_ERROR_RETURN ((
00408                   LM_ERROR,
00409                   ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::visit_union -")
00410                   ACE_TEXT (" visit_scope failed\n")
00411                 ),
00412                 -1
00413               );
00414             }
00415         } // if (CORBA::is_nil (...))
00416       else
00417         {
00418           // Are we seeing the full definition of a previous forward
00419           // declaration. If so, just add the members so the repo
00420           // entry referencing the UnionDef will still be valid.
00421           if (node->ifr_fwd_added ())
00422             {
00423               union_def = CORBA::UnionDef::_narrow (prev_def.in ());
00424               union_def->discriminator_type_def (this->ir_current_.in ());
00425           
00426               if (this->add_members (node, union_def.in ()) == -1)
00427                 {
00428                   ACE_ERROR_RETURN ((
00429                       LM_ERROR,
00430                       ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
00431                       ACE_TEXT ("visit_union -")
00432                       ACE_TEXT (" visit_scope failed\n")
00433                     ),
00434                     -1
00435                   );
00436                 }
00437                 
00438               // We shouldn't see this node again, but just in case.
00439               node->ifr_fwd_added (false);
00440            }
00441            
00442           // Are we clobbering a previous
00443           // entry (from another IDL file) of another type? In that
00444           // case we do what other ORB vendors do, and destroy the
00445           // original entry, create the new one, and let the user beware.
00446           if (!node->ifr_added ())
00447             {
00448               prev_def->destroy ();
00449 
00450               // This call will take the other branch.
00451               return this->visit_union (node);
00452             }
00453 
00454           this->ir_current_ = CORBA::IDLType::_narrow (prev_def.in ());
00455         }
00456     }
00457   catch (const CORBA::Exception& ex)
00458     {
00459       ex._tao_print_exception (
00460         ACE_TEXT (
00461           "ifr_adding_visitor_union::visit_union"));
00462 
00463       return -1;
00464     }
00465 
00466   return 0;
00467 }


Member Data Documentation

CORBA::TypeCode_var ifr_adding_visitor_union::disc_tc_ [private]
 

Definition at line 67 of file ifr_adding_visitor_union.h.

Referenced by visit_union().

bool ifr_adding_visitor_union::is_nested_ [private]
 

Definition at line 59 of file ifr_adding_visitor_union.h.

CORBA::UnionMemberSeq ifr_adding_visitor_union::members_ [private]
 

Definition at line 63 of file ifr_adding_visitor_union.h.

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

Definition at line 72 of file ifr_adding_visitor_union.h.


The documentation for this class was generated from the following files:
Generated on Sun Jan 27 16:32:27 2008 for TAO_IFR by doxygen 1.3.6