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 ()
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 << "::" << fname
<< "_ptr p);" << be_nl
130 << "static void release ("
131 << "::" << fname
<< "_ptr p);" << be_nl
132 << "static ::" << fname
<< "_ptr nil ();" << be_nl
133 << "static ::CORBA::Boolean marshal ("
134 << "const ::" << fname
<< "_ptr p,"
135 << "TAO_OutputCDR & cdr);" << be_uidt_nl
141 if (this->visit_scope (node
) != 0)
143 ACE_ERROR_RETURN ((LM_ERROR
,
144 "(%N:%l) be_visitor_traits::"
145 "visit_interface - visit scope failed\n"),
153 be_visitor_traits::visit_interface_fwd (be_interface_fwd
*node
)
155 if (node
->cli_traits_gen ())
161 dynamic_cast<be_interface
*> (node
->full_definition ());
163 // We want to generate just the declaration of the Arg_Traits<>
164 // specialization if the interface is forward declared but not defined.
165 if (!fd
->is_defined () && this->visit_interface (fd
) != 0)
167 ACE_ERROR_RETURN ((LM_ERROR
,
168 "(%N:%l) be_visitor_traits::"
169 "visit_interface_fwd - code generation failed\n"),
173 node
->cli_traits_gen (true);
178 be_visitor_traits::visit_valuetype (be_valuetype
*node
)
180 if (node
->cli_traits_gen ())
185 /// Some type of recursion can cause fprintf problems,
186 /// easily avoided by setting the flag before visit_scope().
187 node
->cli_traits_gen (true);
189 TAO_OutStream
*os
= this->ctx_
->stream ();
191 // I think we need to generate this only for non-defined forward
193 if (!node
->imported ())
195 os
->gen_ifdef_macro (node
->flat_name (), "traits", false);
198 << "template<>" << be_nl
199 << "struct " << be_global
->stub_export_macro () << " Value_Traits<"
200 << node
->name () << ">" << be_nl
202 << "static void add_ref (" << node
->name () << " *);" << be_nl
203 << "static void remove_ref (" << node
->name () << " *);"
205 << "static void release (" << node
->name () << " *);"
212 int status
= this->visit_scope (node
);
216 ACE_ERROR_RETURN ((LM_ERROR
,
217 "(%N:%l) be_visitor_traits::"
218 "visit_valuetype - visit scope failed\n"),
226 be_visitor_traits::visit_valuetype_fwd (be_valuetype_fwd
*node
)
228 if (node
->cli_traits_gen ())
234 dynamic_cast<be_valuetype
*> (node
->full_definition ());
236 // The logic in visit_valuetype() should handle what gets generated
238 int status
= this->visit_valuetype (fd
);
242 ACE_ERROR_RETURN ((LM_ERROR
,
243 "(%N:%l) be_visitor_traits::"
244 "visit_valuetype_fwd - code generation failed\n"),
248 node
->cli_traits_gen (true);
253 be_visitor_traits::visit_valuebox (be_valuebox
*node
)
255 if (node
->cli_traits_gen ())
260 TAO_OutStream
*os
= this->ctx_
->stream ();
262 // I think we need to generate this only for non-defined forward
264 if (!node
->imported ())
266 os
->gen_ifdef_macro (node
->flat_name (), "traits", false);
269 << "template<>" << be_nl
270 << "struct " << be_global
->stub_export_macro () << " Value_Traits<"
271 << node
->name () << ">" << be_nl
273 << "static void add_ref (" << node
->name () << " *);" << be_nl
274 << "static void remove_ref (" << node
->name () << " *);"
276 << "static void release (" << node
->name () << " *);"
283 node
->cli_traits_gen (true);
288 be_visitor_traits::visit_component (be_component
*node
)
290 return this->visit_interface (node
);
294 be_visitor_traits::visit_connector (be_connector
*node
)
296 return this->visit_component (node
);
300 be_visitor_traits::visit_component_fwd (be_component_fwd
*node
)
302 return this->visit_interface_fwd (node
);
306 be_visitor_traits::visit_eventtype (be_eventtype
*node
)
308 return this->visit_valuetype (node
);
312 be_visitor_traits::visit_eventtype_fwd (be_eventtype_fwd
*node
)
314 return this->visit_valuetype_fwd (node
);
318 be_visitor_traits::visit_field (be_field
*node
)
320 be_type
*ft
= dynamic_cast<be_type
*> (node
->field_type ());
322 if (ft
->accept (this) == -1)
324 ACE_ERROR_RETURN ((LM_ERROR
,
325 "(%N:%l) be_visitor_traits::"
326 "visit_field - visit field type failed\n"),
334 be_visitor_traits::visit_union_branch (be_union_branch
*node
)
336 be_type
*ft
= dynamic_cast<be_type
*> (node
->field_type ());
337 AST_Decl::NodeType nt
= ft
->node_type ();
339 // All we are trying to catch in here are anonymous array members.
340 if (nt
!= AST_Decl::NT_array
)
345 if (ft
->accept (this) == -1)
347 ACE_ERROR_RETURN ((LM_ERROR
,
348 "(%N:%l) be_visitor_traits::"
349 "visit_union_branch - visit field type failed\n"),
357 be_visitor_traits::visit_exception (be_exception
*node
)
359 if (this->visit_scope (node
) == -1)
361 ACE_ERROR_RETURN ((LM_ERROR
,
362 "(%N:%l) be_visitor_traits::"
363 "visit_exception - visit scope failed\n"),
371 be_visitor_traits::visit_structure (be_structure
*node
)
373 if (this->visit_scope (node
) == -1)
375 ACE_ERROR_RETURN ((LM_ERROR
,
376 "(%N:%l) be_visitor_traits::"
377 "visit_struct - visit scope failed\n"),
385 be_visitor_traits::visit_union (be_union
*node
)
387 if (this->visit_scope (node
) == -1)
389 ACE_ERROR_RETURN ((LM_ERROR
,
390 "(%N:%l) be_visitor_traits::"
391 "visit_union - visit scope failed\n"),
399 be_visitor_traits::visit_array (be_array
*node
)
401 if (node
->imported () || node
->cli_traits_gen ())
406 ACE_CString name_holder
;
408 if (node
->is_nested ())
411 dynamic_cast<be_scope
*> (node
->defined_in ())->decl ();
412 name_holder
= parent
->full_name ();
416 if (!this->ctx_
->alias ())
421 name_holder
+= node
->local_name ()->get_string ();
425 name_holder
= node
->full_name ();
428 const char *name
= name_holder
.fast_rep ();
430 TAO_OutStream
*os
= this->ctx_
->stream ();
432 //FUZZ: disable check_for_lack_ACE_OS
434 << "template<>" << be_nl
435 << "struct " << be_global
->stub_export_macro () << " Array_Traits<"
436 << be_idt
<< be_idt_nl
437 << name
<< "_forany" << be_uidt_nl
440 << "static void free (" << be_idt
<< be_idt_nl
441 << name
<< "_slice * _tao_slice);"
444 << "static " << name
<< "_slice * dup ("
445 << be_idt
<< be_idt_nl
446 << "const " << name
<< "_slice * _tao_slice);"
449 << "static void copy (" << be_idt
<< be_idt_nl
450 << name
<< "_slice * _tao_to," << be_nl
451 << "const " << name
<< "_slice * _tao_from);"
454 << "static " << name
<< "_slice * alloc ();"
456 << "static void zero (" << be_idt
<< be_idt_nl
457 << name
<< "_slice * _tao_slice);"
462 //FUZZ: enable check_for_lack_ACE_OS
464 node
->cli_traits_gen (true);
469 be_visitor_traits::visit_typedef (be_typedef
*node
)
471 this->ctx_
->alias (node
);
473 // Make a decision based on the primitive base type.
474 be_type
*bt
= node
->primitive_base_type ();
476 if (!bt
|| (bt
->accept (this) == -1))
478 ACE_ERROR_RETURN ((LM_ERROR
,
479 "(%N:%l) be_visitor_traits::"
481 "Bad primitive type\n"),
485 this->ctx_
->alias (nullptr);
486 node
->cli_traits_gen (true);