Merge pull request #1551 from DOCGroup/plm_jira_333
[ACE_TAO.git] / TAO / orbsvcs / IFR_Service / ifr_adding_visitor_structure.cpp
blob19227166b8e7ee5de25fa440851c3c1d248f22c3
1 /* -*- c++ -*- */
2 #include "orbsvcs/Log_Macros.h"
3 #include "ast_enum.h"
4 #include "ast_expression.h"
5 #include "ast_field.h"
6 #include "ast_union.h"
7 #include "utl_identifier.h"
9 #include "ifr_adding_visitor_structure.h"
10 #include "ifr_adding_visitor_union.h"
12 ifr_adding_visitor_structure::ifr_adding_visitor_structure (AST_Decl *scope)
13 : ifr_adding_visitor (scope)
17 ifr_adding_visitor_structure::~ifr_adding_visitor_structure (void)
21 // Specialized visit_scope method for stucts only.
22 int
23 ifr_adding_visitor_structure::visit_scope (UTL_Scope *node)
25 // If the struct has members that are scopes but not structs,
26 // the regular visit_scope method should be called instead.
27 if (node->scope_node_type () != AST_Decl::NT_struct)
29 return ifr_adding_visitor::visit_scope (node);
32 AST_Structure *s = dynamic_cast<AST_Structure*> (node);
33 CORBA::ULong const nfields = static_cast<CORBA::ULong> (s->nfields ());
34 this->members_.length (nfields);
35 AST_Field **f = 0;
37 try
39 // Visit each field.
40 for (CORBA::ULong i = 0; i < nfields; ++i)
42 if (s->field (f, i) != 0)
44 ORBSVCS_ERROR_RETURN ((
45 LM_ERROR,
46 ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::")
47 ACE_TEXT ("visit_scope -")
48 ACE_TEXT (" field node access failed\n")),
49 -1);
52 AST_Type *ft = (*f)->field_type ();
53 bool defined_here = ft->is_child (this->scope_);
55 // If the struct member is defined in the struct, we have to
56 // do some visiting - otherwise we can just look up the entry.
57 if (defined_here)
59 if (ft->node_type () == AST_Decl::NT_struct)
61 // Since the enclosing scope hasn't been created yet,
62 // we make a special visitor to create this member
63 // at global scope and move it into the struct later.
64 ifr_adding_visitor_structure visitor (ft);
66 if (ft->ast_accept (&visitor) == -1)
68 ORBSVCS_ERROR_RETURN ((
69 LM_ERROR,
70 ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::")
71 ACE_TEXT ("visit_scope -")
72 ACE_TEXT (" failed to accept visitor\n")),
73 -1);
76 this->ir_current_ =
77 CORBA::IDLType::_duplicate (visitor.ir_current ());
79 else
81 if (ft->ast_accept (this) == -1)
83 ORBSVCS_ERROR_RETURN ((
84 LM_ERROR,
85 ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::")
86 ACE_TEXT ("visit_scope -")
87 ACE_TEXT (" failed to accept visitor\n")),
88 -1);
92 else
94 // Updates ir_current_.
95 this->get_referenced_type (ft);
98 this->members_[i].name =
99 CORBA::string_dup ((*f)->local_name ()->get_string ());
101 // IfR method create_struct does not use this - it just needs
102 // to be non-zero for marshaling.
103 this->members_[i].type =
104 CORBA::TypeCode::_duplicate (CORBA::_tc_void);
106 this->members_[i].type_def =
107 CORBA::IDLType::_duplicate (this->ir_current_.in ());
110 catch (const CORBA::Exception& ex)
112 ex._tao_print_exception (
113 ACE_TEXT (
114 "ifr_adding_visitor_structure::visit_scope"));
116 return -1;
119 return 0;
123 ifr_adding_visitor_structure::visit_structure (AST_Structure *node)
127 CORBA::StructDef_var struct_def;
128 CORBA::Contained_var prev_def =
129 be_global->repository ()->lookup_id (node->repoID ());
131 if (CORBA::is_nil (prev_def.in ()))
133 CORBA::StructDef_var struct_def;
134 CORBA::StructMemberSeq dummyMembers;
135 dummyMembers.length (0);
137 CORBA::Container_ptr current_scope = CORBA::Container::_nil ();
139 if (be_global->ifr_scopes ().top (current_scope) != 0)
141 ORBSVCS_ERROR_RETURN ((
142 LM_ERROR,
143 ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::")
144 ACE_TEXT ("visit_structure -")
145 ACE_TEXT (" scope stack is empty\n")),
146 -1);
149 // First create the named structure without any members.
150 struct_def =
151 current_scope->create_struct (
152 node->repoID (),
153 node->local_name ()->get_string (),
154 node->version (),
155 dummyMembers
158 if (be_global->ifr_scopes ().push (struct_def.in ()) != 0)
160 ORBSVCS_ERROR_RETURN ((
161 LM_ERROR,
162 ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::")
163 ACE_TEXT ("visit_structure -")
164 ACE_TEXT (" scope push failed\n")
170 // Then add the real structure members (which corrupts ir_current_).
171 if (this->add_members (node, struct_def.in ()) == -1)
173 ORBSVCS_ERROR_RETURN ((
174 LM_ERROR,
175 ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::")
176 ACE_TEXT ("visit_structure -")
177 ACE_TEXT (" visit_scope failed\n")),
178 -1);
181 this->ir_current_ = CORBA::IDLType::_narrow (struct_def.in ());
183 CORBA::Container_ptr used_scope =
184 CORBA::Container::_nil ();
186 // Pop the new IR object back off the scope stack.
187 if (be_global->ifr_scopes ().pop (used_scope) != 0)
189 ORBSVCS_ERROR_RETURN ((
190 LM_ERROR,
191 ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::")
192 ACE_TEXT ("visit_structure -")
193 ACE_TEXT (" scope pop failed\n")
198 } // if (CORBA::is_nil (...))
199 else
201 // We are seeing the full definition of a forward
202 // declaration - just add the members so repo
203 // entries referencing the UnionDef will stay valid.
204 // Also we know node->ifr_fwd_added_ is true.
205 struct_def = CORBA::StructDef::_narrow (prev_def.in ());
207 if (be_global->ifr_scopes ().push (struct_def.in ()) != 0)
209 ORBSVCS_ERROR_RETURN ((
210 LM_ERROR,
211 ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::")
212 ACE_TEXT ("visit_structure -")
213 ACE_TEXT (" scope push failed\n")
219 if (this->add_members (node, struct_def.in ()) == -1)
221 ORBSVCS_ERROR_RETURN ((
222 LM_ERROR,
223 ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::")
224 ACE_TEXT ("visit_structure -")
225 ACE_TEXT (" visit_scope failed\n")),
226 -1);
229 this->ir_current_ = CORBA::IDLType::_narrow (prev_def.in ());
231 CORBA::Container_ptr used_scope =
232 CORBA::Container::_nil ();
234 // Pop the new IR object back off the scope stack.
235 if (be_global->ifr_scopes ().pop (used_scope) != 0)
237 ORBSVCS_ERROR_RETURN ((
238 LM_ERROR,
239 ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::")
240 ACE_TEXT ("visit_structure -")
241 ACE_TEXT (" scope pop failed\n")
248 catch (const CORBA::Exception& ex)
250 ex._tao_print_exception (
251 ACE_TEXT (
252 "ifr_adding_visitor_structure::visit_structure"));
254 return -1;
257 return 0;
261 ifr_adding_visitor_structure::visit_enum (AST_Enum *node)
265 // Is this enum already in the respository?
266 CORBA::Contained_var prev_def =
267 be_global->repository ()->lookup_id (node->repoID ());
269 // If not, create a new entry.
270 if (CORBA::is_nil (prev_def.in ()))
272 CORBA::ULong member_count =
273 static_cast<CORBA::ULong> (node->member_count ());
275 CORBA::EnumMemberSeq members (member_count);
276 members.length (member_count);
278 UTL_ScopedName *member_name = 0;
280 // Get a list of the member names.
281 for (CORBA::ULong i = 0; i < member_count; ++i)
283 member_name = node->value_to_name (i);
285 members[i] =
286 CORBA::string_dup (
287 member_name->last_component ()->get_string ()
291 this->ir_current_ =
292 be_global->repository ()->create_enum (
293 node->repoID (),
294 node->local_name ()->get_string (),
295 node->version (),
296 members
299 node->ifr_added (true);
301 else
303 // If the line below is true, we are clobbering a previous
304 // entry (from another IDL file) of another type. In that
305 // case we do what other ORB vendors do, and destroy the
306 // original entry, create the new one, and let the user beware.
307 if (!node->ifr_added ())
309 prev_def->destroy ();
311 // This call will take the other branch.
312 return this->visit_enum (node);
315 this->ir_current_ =
316 CORBA::IDLType::_narrow (prev_def.in ());
319 catch (const CORBA::Exception& ex)
321 ex._tao_print_exception (
322 ACE_TEXT (
323 "ifr_adding_visitor_structure::visit_enum"));
325 return -1;
328 return 0;
332 ifr_adding_visitor_structure::visit_union (AST_Union *node)
336 // Is this union already in the respository?
337 CORBA::Contained_var prev_def =
338 be_global->repository ()->lookup_id (node->repoID ());
340 // If not, create a new entry.
341 if (CORBA::is_nil (prev_def.in ()))
343 ifr_adding_visitor_union visitor (node);
344 int retval = visitor.visit_union (node);
346 if (retval == 0)
348 // Get the result of the visit.
349 this->ir_current_ =
350 CORBA::IDLType::_duplicate (visitor.ir_current ());
353 return retval;
355 else
357 // If the line below is true, we are clobbering a previous
358 // entry (from another IDL file) of another type. In that
359 // case we do what other ORB vendors do, and destroy the
360 // original entry, create the new one, and let the user beware.
361 if (!node->ifr_added ())
363 prev_def->destroy ();
365 // This call will take the other branch.
366 return this->visit_union (node);
369 this->ir_current_ =
370 CORBA::IDLType::_narrow (prev_def.in ());
373 catch (const CORBA::Exception& ex)
375 ex._tao_print_exception (
376 ACE_TEXT (
377 "ifr_adding_visitor_structure::visit_union"));
379 return -1;
382 return 0;
385 CORBA::IDLType_ptr
386 ifr_adding_visitor_structure::ir_current (void) const
388 return this->ir_current_.in ();
392 ifr_adding_visitor_structure::add_members (AST_Structure *node,
393 CORBA::StructDef_ptr struct_def)
395 if (this->visit_scope (node) == -1)
397 ORBSVCS_ERROR_RETURN ((
398 LM_ERROR,
399 ACE_TEXT ("(%N:%l) ifr_adding_visitor_structure::")
400 ACE_TEXT ("visit_structure -")
401 ACE_TEXT (" visit_scope failed\n")),
402 -1);
405 // Correct ir_current_ and move the real members into the struct.
406 this->ir_current_= CORBA::StructDef::_duplicate (struct_def);
407 struct_def->members (this->members_);
409 node->ifr_added (true);
410 return 0;