00001
00002
00003
00004 #include "ast_enum.h"
00005 #include "ast_expression.h"
00006 #include "ast_union.h"
00007 #include "ast_union_branch.h"
00008 #include "ast_union_label.h"
00009 #include "utl_identifier.h"
00010
00011 #include "ifr_adding_visitor_union.h"
00012 #include "ifr_adding_visitor_structure.h"
00013
00014 #include "tao/AnyTypeCode/Any_Unknown_IDL_Type.h"
00015 #include "tao/CDR.h"
00016
00017 ACE_RCSID (IFR_Service,
00018 ifr_adding_visitor_union,
00019 "$Id: ifr_adding_visitor_union.cpp 78850 2007-07-12 10:50:02Z parsons $")
00020
00021 ifr_adding_visitor_union::ifr_adding_visitor_union (
00022 AST_Decl *scope,
00023 bool is_nested
00024 )
00025 : ifr_adding_visitor (scope),
00026 is_nested_ (is_nested)
00027 {
00028 }
00029
00030 ifr_adding_visitor_union::~ifr_adding_visitor_union (void)
00031 {
00032 }
00033
00034
00035 int
00036 ifr_adding_visitor_union::visit_scope (UTL_Scope *node)
00037 {
00038
00039
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
00054 CORBA::ULong index = 0;
00055
00056 try
00057 {
00058
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
00078
00079 if (defined_here)
00080 {
00081 if (ft->node_type () == AST_Decl::NT_union)
00082 {
00083
00084
00085
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
00126 this->get_referenced_type (ft);
00127 }
00128
00129
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
00136
00137
00138
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
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
00155
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
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
00185
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 }
00205
00206 int
00207 ifr_adding_visitor_union::visit_structure (AST_Structure *node)
00208 {
00209 try
00210 {
00211
00212 CORBA::Contained_var prev_def =
00213 be_global->repository ()->lookup_id (node->repoID ());
00214
00215
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
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
00233
00234
00235
00236 this->move_queue_.enqueue_tail (tmp);
00237 }
00238
00239 return retval;
00240 }
00241 else
00242 {
00243
00244
00245
00246
00247 if (!node->ifr_added ())
00248 {
00249 prev_def->destroy ();
00250
00251
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 }
00270
00271 int
00272 ifr_adding_visitor_union::visit_enum (AST_Enum *node)
00273 {
00274 try
00275 {
00276
00277 CORBA::Contained_var prev_def =
00278 be_global->repository ()->lookup_id (node->repoID ());
00279
00280
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
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
00311
00312
00313
00314 this->move_queue_.enqueue_tail (tmp);
00315
00316 node->ifr_added (true);
00317 }
00318 else
00319 {
00320
00321
00322
00323
00324 if (!node->ifr_added ())
00325 {
00326 prev_def->destroy ();
00327
00328
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 }
00347
00348 int
00349 ifr_adding_visitor_union::visit_union (AST_Union *node)
00350 {
00351 try
00352 {
00353
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
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
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 }
00416 else
00417 {
00418
00419
00420
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
00439 node->ifr_fwd_added (false);
00440 }
00441
00442
00443
00444
00445
00446 if (!node->ifr_added ())
00447 {
00448 prev_def->destroy ();
00449
00450
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 }
00468
00469 CORBA::IDLType_ptr
00470 ifr_adding_visitor_union::ir_current (void) const
00471 {
00472 return this->ir_current_.in ();
00473 }
00474
00475 int
00476 ifr_adding_visitor_union::add_members (AST_Union *node,
00477 CORBA::UnionDef_ptr union_def)
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
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 }