1 //=============================================================================
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"
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"
28 #include "be_union_branch.h"
29 #include "be_exception.h"
30 #include "be_structure.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)
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
);
61 << be_global
->core_versioning_begin ();
64 << "// Traits specializations." << be_nl
65 << "namespace TAO" << be_nl
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"),
79 *os
<< be_global
->core_versioning_end () << be_nl
;
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"),
100 be_visitor_traits::visit_interface (be_interface
*node
)
102 if (node
->cli_traits_gen ())
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 ();
124 << "template<>" << be_nl
125 << "struct " << be_global
->stub_export_macro () << " Objref_Traits<"
126 << " ::" << fname
<< ">" << be_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
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"),
154 be_visitor_traits::visit_interface_fwd (be_interface_fwd
*node
)
156 if (node
->cli_traits_gen ())
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"),
174 node
->cli_traits_gen (true);
179 be_visitor_traits::visit_valuetype (be_valuetype
*node
)
181 if (node
->cli_traits_gen ())
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
194 if (!node
->imported ())
196 os
->gen_ifdef_macro (node
->flat_name (), "traits", false);
199 << "template<>" << be_nl
200 << "struct " << be_global
->stub_export_macro () << " Value_Traits<"
201 << node
->name () << ">" << be_nl
203 << "static void add_ref (" << node
->name () << " *);" << be_nl
204 << "static void remove_ref (" << node
->name () << " *);"
206 << "static void release (" << node
->name () << " *);"
213 int status
= this->visit_scope (node
);
217 ACE_ERROR_RETURN ((LM_ERROR
,
218 "(%N:%l) be_visitor_traits::"
219 "visit_valuetype - visit scope failed\n"),
227 be_visitor_traits::visit_valuetype_fwd (be_valuetype_fwd
*node
)
229 if (node
->cli_traits_gen ())
235 dynamic_cast<be_valuetype
*> (node
->full_definition ());
237 // The logic in visit_valuetype() should handle what gets generated
239 int status
= this->visit_valuetype (fd
);
243 ACE_ERROR_RETURN ((LM_ERROR
,
244 "(%N:%l) be_visitor_traits::"
245 "visit_valuetype_fwd - code generation failed\n"),
249 node
->cli_traits_gen (true);
254 be_visitor_traits::visit_valuebox (be_valuebox
*node
)
256 if (node
->cli_traits_gen ())
261 TAO_OutStream
*os
= this->ctx_
->stream ();
263 // I think we need to generate this only for non-defined forward
265 if (!node
->imported ())
267 os
->gen_ifdef_macro (node
->flat_name (), "traits", false);
270 << "template<>" << be_nl
271 << "struct " << be_global
->stub_export_macro () << " Value_Traits<"
272 << node
->name () << ">" << be_nl
274 << "static void add_ref (" << node
->name () << " *);" << be_nl
275 << "static void remove_ref (" << node
->name () << " *);"
277 << "static void release (" << node
->name () << " *);"
284 node
->cli_traits_gen (true);
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"),
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
)
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"),
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"),
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"),
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"),
400 be_visitor_traits::visit_array (be_array
*node
)
402 if (node
->imported () || node
->cli_traits_gen ())
407 ACE_CString name_holder
;
409 if (node
->is_nested ())
412 dynamic_cast<be_scope
*> (node
->defined_in ())->decl ();
413 name_holder
= parent
->full_name ();
417 if (!this->ctx_
->alias ())
422 name_holder
+= node
->local_name ()->get_string ();
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
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
441 << "static void free (" << be_idt
<< be_idt_nl
442 << name
<< "_slice * _tao_slice);"
445 << "static " << name
<< "_slice * dup ("
446 << be_idt
<< be_idt_nl
447 << "const " << name
<< "_slice * _tao_slice);"
450 << "static void copy (" << be_idt
<< be_idt_nl
451 << name
<< "_slice * _tao_to," << be_nl
452 << "const " << name
<< "_slice * _tao_from);"
455 << "static " << name
<< "_slice * alloc (void);"
457 << "static void zero (" << be_idt
<< be_idt_nl
458 << name
<< "_slice * _tao_slice);"
463 //FUZZ: enable check_for_lack_ACE_OS
465 node
->cli_traits_gen (true);
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::"
482 "Bad primitive type\n"),
486 this->ctx_
->alias (0);
487 node
->cli_traits_gen (true);