Merge pull request #2303 from jwillemsen/jwi-803
[ACE_TAO.git] / TAO / orbsvcs / IFR_Service / ifr_adding_visitor_exception.cpp
blob10ce5c043da18d90477a052acae71d41b0941dd3
1 /* -*- c++ -*- */
2 #include "orbsvcs/Log_Macros.h"
3 #include "ast_enum.h"
4 #include "ast_exception.h"
5 #include "ast_expression.h"
6 #include "ast_field.h"
7 #include "ast_union.h"
8 #include "utl_identifier.h"
10 #include "ifr_adding_visitor_exception.h"
11 #include "ifr_adding_visitor_structure.h"
12 #include "ifr_adding_visitor_union.h"
14 ifr_adding_visitor_exception::ifr_adding_visitor_exception (
15 AST_Decl *scope,
16 bool in_reopened
18 : ifr_adding_visitor (scope,
19 in_reopened)
23 ifr_adding_visitor_exception::~ifr_adding_visitor_exception ()
27 // Specialized visit_scope method for exceptions only.
28 int
29 ifr_adding_visitor_exception::visit_scope (UTL_Scope *node)
31 // If the exception has members that are scopes but not exceptions,
32 // the regular visit_scope method should be called instead.
33 if (node->scope_node_type () != AST_Decl::NT_except)
35 return ifr_adding_visitor::visit_scope (node);
38 AST_Exception *e = dynamic_cast<AST_Exception*> (node);
40 CORBA::ULong const nfields = static_cast<CORBA::ULong> (e->nfields ());
42 this->members_.length (nfields);
44 AST_Field **f = 0;
46 try
48 // Visit each field.
49 for (CORBA::ULong i = 0; i < nfields; ++i)
51 if (e->field (f, i) != 0)
53 ORBSVCS_ERROR_RETURN ((
54 LM_ERROR,
55 ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
56 ACE_TEXT ("visit_scope -")
57 ACE_TEXT (" field node access failed\n")
63 AST_Type *ft = (*f)->field_type ();
65 bool defined_here = ft->is_child (this->scope_);
67 // If the struct member is defined in the struct, we have to
68 // do some visiting - otherwise we can just look up the entry.
69 if (defined_here)
71 if (ft->ast_accept (this) == -1)
73 ORBSVCS_ERROR_RETURN ((
74 LM_ERROR,
75 ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
76 ACE_TEXT ("visit_scope -")
77 ACE_TEXT (" failed to accept visitor\n")
83 else
85 // Updates ir_current_.
86 this->get_referenced_type (ft);
89 this->members_[i].name =
90 CORBA::string_dup ((*f)->local_name ()->get_string ());
92 // IfR method create_exception does not use this - it just needs
93 // to be non-zero for marshaling.
94 this->members_[i].type =
95 CORBA::TypeCode::_duplicate (CORBA::_tc_void);
97 this->members_[i].type_def =
98 CORBA::IDLType::_duplicate (this->ir_current_.in ());
101 catch (const CORBA::Exception& ex)
103 ex._tao_print_exception (
104 ACE_TEXT (
105 "ifr_adding_visitor_structure::visit_scope"));
107 return -1;
110 return 0;
114 ifr_adding_visitor_exception::visit_structure (AST_Structure *node)
118 // Is this union already in the respository?
119 CORBA::Contained_var prev_def =
120 be_global->repository ()->lookup_id (node->repoID ());
122 // If not, create a new entry.
123 if (CORBA::is_nil (prev_def.in ()))
125 ifr_adding_visitor_structure visitor (node);
126 int retval = visitor.visit_structure (node);
128 if (retval == 0)
130 // Get the result of the visit.
131 this->ir_current_ =
132 CORBA::IDLType::_duplicate (visitor.ir_current ());
135 return retval;
137 else
139 // If the line below is true, we are clobbering a previous
140 // entry (from another IDL file) of another type. In that
141 // case we do what other ORB vendors do, and destroy the
142 // original entry, create the new one, and let the user beware.
143 if (!node->ifr_added ())
145 prev_def->destroy ();
147 // This call will take the other branch.
148 return this->visit_structure (node);
151 this->ir_current_ =
152 CORBA::IDLType::_narrow (prev_def.in ());
155 catch (const CORBA::Exception& ex)
157 ex._tao_print_exception (
158 ACE_TEXT (
159 "ifr_adding_visitor_exception::visit_structure"));
161 return -1;
164 return 0;
168 ifr_adding_visitor_exception::visit_exception (AST_Exception *node)
172 CORBA::ExceptionDef_var new_def;
173 CORBA::Contained_var prev_def =
174 be_global->repository ()->lookup_id (node->repoID ());
176 if (CORBA::is_nil (prev_def.in ()))
178 CORBA::StructMemberSeq dummyMembers;
179 dummyMembers.length (0);
180 CORBA::Container_ptr current_scope =
181 CORBA::Container::_nil ();
183 if (be_global->ifr_scopes ().top (current_scope) != 0)
185 ORBSVCS_ERROR_RETURN ((
186 LM_ERROR,
187 ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
188 ACE_TEXT ("visit_exception -")
189 ACE_TEXT (" scope stack is empty\n")
195 new_def =
196 current_scope->create_exception (node->repoID (),
197 node->local_name ()->get_string (),
198 node->version (),
199 dummyMembers);
201 if (be_global->ifr_scopes ().push (new_def.in ()) != 0)
203 ORBSVCS_ERROR_RETURN ((
204 LM_ERROR,
205 ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
206 ACE_TEXT ("visit_exception -")
207 ACE_TEXT (" scope push failed\n")
213 // Then add the real exception members.
214 if (this->add_members (node, new_def.in ()) == -1)
216 ORBSVCS_ERROR_RETURN ((
217 LM_ERROR,
218 ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
219 ACE_TEXT ("visit_exception -")
220 ACE_TEXT (" visit_scope failed\n")),
221 -1);
224 CORBA::Container_ptr used_scope =
225 CORBA::Container::_nil ();
227 // Pop the new IR object back off the scope stack.
228 if (be_global->ifr_scopes ().pop (used_scope) != 0)
230 ORBSVCS_ERROR_RETURN ((
231 LM_ERROR,
232 ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
233 ACE_TEXT ("visit_exception -")
234 ACE_TEXT (" scope pop failed\n")
240 else
242 new_def = CORBA::ExceptionDef::_narrow (prev_def.in ());
244 if (be_global->ifr_scopes ().push (new_def.in ()) != 0)
246 ORBSVCS_ERROR_RETURN ((
247 LM_ERROR,
248 ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
249 ACE_TEXT ("visit_exception -")
250 ACE_TEXT (" scope push failed\n")
256 // Then add the real exception members.
257 if (this->add_members (node, new_def.in ()) == -1)
259 ORBSVCS_ERROR_RETURN ((
260 LM_ERROR,
261 ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
262 ACE_TEXT ("visit_exception -")
263 ACE_TEXT (" visit_scope failed\n")),
264 -1);
267 CORBA::Container_ptr used_scope =
268 CORBA::Container::_nil ();
270 // Pop the new IR object back off the scope stack.
271 if (be_global->ifr_scopes ().pop (used_scope) != 0)
273 ORBSVCS_ERROR_RETURN ((
274 LM_ERROR,
275 ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
276 ACE_TEXT ("visit_exception -")
277 ACE_TEXT (" scope pop failed\n")
284 catch (const CORBA::Exception& ex)
286 ex._tao_print_exception (
287 ACE_TEXT (
288 "ifr_adding_visitor_exception::visit_exception"));
290 return -1;
293 return 0;
297 ifr_adding_visitor_exception::visit_enum (AST_Enum *node)
301 // Is this enum already in the respository?
302 CORBA::Contained_var prev_def =
303 be_global->repository ()->lookup_id (node->repoID ());
305 // If not, create a new entry.
306 if (CORBA::is_nil (prev_def.in ()))
308 CORBA::ULong member_count = static_cast<CORBA::ULong> (node->member_count ());
310 CORBA::EnumMemberSeq members (member_count);
311 members.length (member_count);
313 UTL_ScopedName *member_name = 0;
315 // Get a list of the member names.
316 for (CORBA::ULong i = 0; i < member_count; ++i)
318 member_name = node->value_to_name (i);
320 members[i] =
321 CORBA::string_dup (
322 member_name->last_component ()->get_string ()
326 this->ir_current_ =
327 be_global->repository ()->create_enum (
328 node->repoID (),
329 node->local_name ()->get_string (),
330 node->version (),
331 members
334 node->ifr_added (true);
336 else
338 // If the line below is true, we are clobbering a previous
339 // entry (from another IDL file) of another type. In that
340 // case we do what other ORB vendors do, and destroy the
341 // original entry, create the new one, and let the user beware.
342 if (!node->ifr_added ())
344 prev_def->destroy ();
346 // This call will take the other branch.
347 return this->visit_enum (node);
350 this->ir_current_ =
351 CORBA::IDLType::_narrow (prev_def.in ());
354 catch (const CORBA::Exception& ex)
356 ex._tao_print_exception (
357 ACE_TEXT (
358 "ifr_adding_visitor_exception::visit_enum"));
360 return -1;
363 return 0;
367 ifr_adding_visitor_exception::visit_union (AST_Union *node)
371 // Is this union already in the respository?
372 CORBA::Contained_var prev_def =
373 be_global->repository ()->lookup_id (node->repoID ());
375 // If not, create a new entry.
376 if (CORBA::is_nil (prev_def.in ()))
378 ifr_adding_visitor_union visitor (node);
379 int retval = visitor.visit_union (node);
381 if (retval == 0)
383 // Get the result of the visit.
384 this->ir_current_ =
385 CORBA::IDLType::_duplicate (visitor.ir_current ());
388 return retval;
390 else
392 // If the line below is true, we are clobbering a previous
393 // entry (from another IDL file) of another type. In that
394 // case we do what other ORB vendors do, and destroy the
395 // original entry, create the new one, and let the user beware.
396 if (!node->ifr_added ())
398 prev_def->destroy ();
400 // This call will take the other branch.
401 return this->visit_union (node);
404 this->ir_current_ =
405 CORBA::IDLType::_narrow (prev_def.in ());
408 catch (const CORBA::Exception& ex)
410 ex._tao_print_exception (
411 ACE_TEXT (
412 "ifr_adding_visitor_exception::visit_union"));
414 return -1;
417 return 0;
420 CORBA::IDLType_ptr
421 ifr_adding_visitor_exception::ir_current () const
423 return this->ir_current_.in ();
427 ifr_adding_visitor_exception::add_members (AST_Exception *node,
428 CORBA::ExceptionDef_ptr except_def)
430 if (this->visit_scope (node) == -1)
432 ORBSVCS_ERROR_RETURN ((
433 LM_ERROR,
434 ACE_TEXT ("(%N:%l) ifr_adding_visitor_exception::")
435 ACE_TEXT ("visit_exception -")
436 ACE_TEXT (" visit_scope failed\n")
442 except_def->members (this->members_);
444 node->ifr_added (true);
445 return 0;