Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_traits.cpp
blobfc0621241b44fcdd26bd4c2d3109536fcdb63569
1 //=============================================================================
2 /**
3 * @file be_visitor_traits.cpp
5 * This visitor generates template specializations for traits of various
6 * kinds for IDL declarations. These specialized template classes are then
7 * used in other template classes in the ORB.
9 * @author Jeff Parsons <j.parsons@vanderbilt.edu>
11 //=============================================================================
13 #include "be_visitor_traits.h"
14 #include "be_visitor_context.h"
15 #include "be_root.h"
16 #include "be_module.h"
17 #include "be_interface.h"
18 #include "be_valuebox.h"
19 #include "be_valuetype.h"
20 #include "be_valuebox.h"
21 #include "be_interface_fwd.h"
22 #include "be_valuetype_fwd.h"
23 #include "be_eventtype.h"
24 #include "be_eventtype_fwd.h"
25 #include "be_connector.h"
26 #include "be_component_fwd.h"
27 #include "be_field.h"
28 #include "be_union_branch.h"
29 #include "be_exception.h"
30 #include "be_structure.h"
31 #include "be_union.h"
32 #include "be_array.h"
33 #include "be_typedef.h"
34 #include "be_helper.h"
35 #include "be_extern.h"
37 #include "utl_identifier.h"
38 #include "idl_defines.h"
40 #include "ace/Log_Msg.h"
42 be_visitor_traits::be_visitor_traits (be_visitor_context *ctx)
43 : be_visitor_scope (ctx)
47 be_visitor_traits::~be_visitor_traits (void)
51 int
52 be_visitor_traits::visit_root (be_root *node)
54 if (be_global->gen_arg_traits ())
56 TAO_OutStream *os = this->ctx_->stream ();
58 TAO_INSERT_COMMENT (os);
60 *os << be_nl
61 << be_global->core_versioning_begin ();
63 *os << be_nl
64 << "// Traits specializations." << be_nl
65 << "namespace TAO" << be_nl
66 << "{" << be_idt;
68 if (this->visit_scope (node) == -1)
70 ACE_ERROR_RETURN ((LM_ERROR,
71 "(%N:%l) be_visitor_traits::"
72 "visit_root - visit scope failed\n"),
73 -1);
76 *os << be_uidt_nl
77 << "}";
79 *os << be_global->core_versioning_end () << be_nl;
82 return 0;
85 int
86 be_visitor_traits::visit_module (be_module *node)
88 if (this->visit_scope (node) == -1)
90 ACE_ERROR_RETURN ((LM_ERROR,
91 "(%N:%l) be_visitor_traits::"
92 "visit_module - visit scope failed\n"),
93 -1);
96 return 0;
99 int
100 be_visitor_traits::visit_interface (be_interface *node)
102 if (node->cli_traits_gen ())
104 return 0;
107 /// Some type of recursion can cause fprintf problems,
108 /// easily avoided by setting the flag before visit_scope().
109 node->cli_traits_gen (true);
111 TAO_OutStream *os = this->ctx_->stream ();
113 // Since the three blocks below generate specialized (i.e., non-template)
114 // classes, we don't want to generate them unless it's necessary - thus
115 // the ifdef logic surrounding each one.
117 if (!node->imported ())
119 os->gen_ifdef_macro (node->flat_name (), "traits", false);
121 const char *fname = node->full_name ();
123 *os << be_nl_2
124 << "template<>" << be_nl
125 << "struct " << be_global->stub_export_macro () << " Objref_Traits<"
126 << " ::" << fname << ">" << be_nl
127 << "{" << be_idt_nl
128 << "static ::" << fname << "_ptr duplicate ("
129 << be_idt << be_idt_nl
130 << "::" << fname << "_ptr p);" << be_uidt << be_uidt_nl
131 << "static void release (" << be_idt << be_idt_nl
132 << "::" << fname << "_ptr p);" << be_uidt << be_uidt_nl
133 << "static ::" << fname << "_ptr nil (void);" << be_nl
134 << "static ::CORBA::Boolean marshal (" << be_idt << be_idt_nl
135 << "const ::" << fname << "_ptr p," << be_nl
136 << "TAO_OutputCDR & cdr);" << be_uidt << be_uidt << be_uidt_nl
137 << "};";
139 os->gen_endif ();
142 if (this->visit_scope (node) != 0)
144 ACE_ERROR_RETURN ((LM_ERROR,
145 "(%N:%l) be_visitor_traits::"
146 "visit_interface - visit scope failed\n"),
147 -1);
150 return 0;
154 be_visitor_traits::visit_interface_fwd (be_interface_fwd *node)
156 if (node->cli_traits_gen ())
158 return 0;
161 be_interface *fd =
162 dynamic_cast<be_interface*> (node->full_definition ());
164 // We want to generate just the declaration of the Arg_Traits<>
165 // specialization if the interface is forward declared but not defined.
166 if (!fd->is_defined () && this->visit_interface (fd) != 0)
168 ACE_ERROR_RETURN ((LM_ERROR,
169 "(%N:%l) be_visitor_traits::"
170 "visit_interface_fwd - code generation failed\n"),
171 -1);
174 node->cli_traits_gen (true);
175 return 0;
179 be_visitor_traits::visit_valuetype (be_valuetype *node)
181 if (node->cli_traits_gen ())
183 return 0;
186 /// Some type of recursion can cause fprintf problems,
187 /// easily avoided by setting the flag before visit_scope().
188 node->cli_traits_gen (true);
190 TAO_OutStream *os = this->ctx_->stream ();
192 // I think we need to generate this only for non-defined forward
193 // declarations.
194 if (!node->imported ())
196 os->gen_ifdef_macro (node->flat_name (), "traits", false);
198 *os << be_nl_2
199 << "template<>" << be_nl
200 << "struct " << be_global->stub_export_macro () << " Value_Traits<"
201 << node->name () << ">" << be_nl
202 << "{" << be_idt_nl
203 << "static void add_ref (" << node->name () << " *);" << be_nl
204 << "static void remove_ref (" << node->name () << " *);"
205 << be_nl
206 << "static void release (" << node->name () << " *);"
207 << be_uidt_nl
208 << "};";
210 os->gen_endif ();
213 int status = this->visit_scope (node);
215 if (status != 0)
217 ACE_ERROR_RETURN ((LM_ERROR,
218 "(%N:%l) be_visitor_traits::"
219 "visit_valuetype - visit scope failed\n"),
220 -1);
223 return 0;
227 be_visitor_traits::visit_valuetype_fwd (be_valuetype_fwd *node)
229 if (node->cli_traits_gen ())
231 return 0;
234 be_valuetype *fd =
235 dynamic_cast<be_valuetype*> (node->full_definition ());
237 // The logic in visit_valuetype() should handle what gets generated
238 // and what doesn't.
239 int status = this->visit_valuetype (fd);
241 if (status != 0)
243 ACE_ERROR_RETURN ((LM_ERROR,
244 "(%N:%l) be_visitor_traits::"
245 "visit_valuetype_fwd - code generation failed\n"),
246 -1);
249 node->cli_traits_gen (true);
250 return 0;
254 be_visitor_traits::visit_valuebox (be_valuebox *node)
256 if (node->cli_traits_gen ())
258 return 0;
261 TAO_OutStream *os = this->ctx_->stream ();
263 // I think we need to generate this only for non-defined forward
264 // declarations.
265 if (!node->imported ())
267 os->gen_ifdef_macro (node->flat_name (), "traits", false);
269 *os << be_nl_2
270 << "template<>" << be_nl
271 << "struct " << be_global->stub_export_macro () << " Value_Traits<"
272 << node->name () << ">" << be_nl
273 << "{" << be_idt_nl
274 << "static void add_ref (" << node->name () << " *);" << be_nl
275 << "static void remove_ref (" << node->name () << " *);"
276 << be_nl
277 << "static void release (" << node->name () << " *);"
278 << be_uidt_nl
279 << "};";
281 os->gen_endif ();
284 node->cli_traits_gen (true);
285 return 0;
289 be_visitor_traits::visit_component (be_component *node)
291 return this->visit_interface (node);
295 be_visitor_traits::visit_connector (be_connector *node)
297 return this->visit_component (node);
301 be_visitor_traits::visit_component_fwd (be_component_fwd *node)
303 return this->visit_interface_fwd (node);
307 be_visitor_traits::visit_eventtype (be_eventtype *node)
309 return this->visit_valuetype (node);
313 be_visitor_traits::visit_eventtype_fwd (be_eventtype_fwd *node)
315 return this->visit_valuetype_fwd (node);
319 be_visitor_traits::visit_field (be_field *node)
321 be_type *ft = dynamic_cast<be_type*> (node->field_type ());
323 if (ft->accept (this) == -1)
325 ACE_ERROR_RETURN ((LM_ERROR,
326 "(%N:%l) be_visitor_traits::"
327 "visit_field - visit field type failed\n"),
328 -1);
331 return 0;
335 be_visitor_traits::visit_union_branch (be_union_branch *node)
337 be_type *ft = dynamic_cast<be_type*> (node->field_type ());
338 AST_Decl::NodeType nt = ft->node_type ();
340 // All we are trying to catch in here are anonymous array members.
341 if (nt != AST_Decl::NT_array)
343 return 0;
346 if (ft->accept (this) == -1)
348 ACE_ERROR_RETURN ((LM_ERROR,
349 "(%N:%l) be_visitor_traits::"
350 "visit_union_branch - visit field type failed\n"),
351 -1);
354 return 0;
358 be_visitor_traits::visit_exception (be_exception *node)
360 if (this->visit_scope (node) == -1)
362 ACE_ERROR_RETURN ((LM_ERROR,
363 "(%N:%l) be_visitor_traits::"
364 "visit_exception - visit scope failed\n"),
365 -1);
368 return 0;
372 be_visitor_traits::visit_structure (be_structure *node)
374 if (this->visit_scope (node) == -1)
376 ACE_ERROR_RETURN ((LM_ERROR,
377 "(%N:%l) be_visitor_traits::"
378 "visit_struct - visit scope failed\n"),
379 -1);
382 return 0;
386 be_visitor_traits::visit_union (be_union *node)
388 if (this->visit_scope (node) == -1)
390 ACE_ERROR_RETURN ((LM_ERROR,
391 "(%N:%l) be_visitor_traits::"
392 "visit_union - visit scope failed\n"),
393 -1);
396 return 0;
400 be_visitor_traits::visit_array (be_array *node)
402 if (node->imported () || node->cli_traits_gen ())
404 return 0;
407 ACE_CString name_holder;
409 if (node->is_nested ())
411 be_decl *parent =
412 dynamic_cast<be_scope*> (node->defined_in ())->decl ();
413 name_holder = parent->full_name ();
415 name_holder += "::";
417 if (!this->ctx_->alias ())
419 name_holder += "_";
422 name_holder += node->local_name ()->get_string ();
424 else
426 name_holder = node->full_name ();
429 const char *name = name_holder.fast_rep ();
431 TAO_OutStream *os = this->ctx_->stream ();
433 //FUZZ: disable check_for_lack_ACE_OS
434 *os << be_nl
435 << "template<>" << be_nl
436 << "struct " << be_global->stub_export_macro () << " Array_Traits<"
437 << be_idt << be_idt_nl
438 << name << "_forany" << be_uidt_nl
439 << ">" << be_uidt_nl
440 << "{" << be_idt_nl
441 << "static void free (" << be_idt << be_idt_nl
442 << name << "_slice * _tao_slice);"
443 << be_uidt
444 << be_uidt_nl
445 << "static " << name << "_slice * dup ("
446 << be_idt << be_idt_nl
447 << "const " << name << "_slice * _tao_slice);"
448 << be_uidt
449 << be_uidt_nl
450 << "static void copy (" << be_idt << be_idt_nl
451 << name << "_slice * _tao_to," << be_nl
452 << "const " << name << "_slice * _tao_from);"
453 << be_uidt
454 << be_uidt_nl
455 << "static " << name << "_slice * alloc (void);"
456 << be_nl
457 << "static void zero (" << be_idt << be_idt_nl
458 << name << "_slice * _tao_slice);"
459 << be_uidt
460 << be_uidt
461 << be_uidt_nl
462 << "};";
463 //FUZZ: enable check_for_lack_ACE_OS
465 node->cli_traits_gen (true);
466 return 0;
470 be_visitor_traits::visit_typedef (be_typedef *node)
472 this->ctx_->alias (node);
474 // Make a decision based on the primitive base type.
475 be_type *bt = node->primitive_base_type ();
477 if (!bt || (bt->accept (this) == -1))
479 ACE_ERROR_RETURN ((LM_ERROR,
480 "(%N:%l) be_visitor_traits::"
481 "visit_typedef - "
482 "Bad primitive type\n"),
483 -1);
486 this->ctx_->alias (0);
487 node->cli_traits_gen (true);
488 return 0;