Changes to attempt to silence bcc64x
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_arg_traits.cpp
blob86a28c1b5c6d9b4101b9f11d2e94a6f9571d9a56
1 //=============================================================================
2 /**
3 * @file be_visitor_arg_traits.cpp
5 * This visitor generates template specializations for argument traits classes.
7 * @author Jeff Parsons <j.parsons@vanderbilt.edu>
8 */
9 //=============================================================================
11 #include "be_visitor_arg_traits.h"
12 #include "be_visitor_context.h"
13 #include "be_root.h"
14 #include "be_module.h"
15 #include "be_interface.h"
16 #include "be_valuebox.h"
17 #include "be_valuetype.h"
18 #include "be_interface_fwd.h"
19 #include "be_valuetype_fwd.h"
20 #include "be_component_fwd.h"
21 #include "be_connector.h"
22 #include "be_home.h"
23 #include "be_eventtype.h"
24 #include "be_eventtype_fwd.h"
25 #include "be_operation.h"
26 #include "be_attribute.h"
27 #include "be_argument.h"
28 #include "be_array.h"
29 #include "be_enum.h"
30 #include "be_predefined_type.h"
31 #include "be_sequence.h"
32 #include "be_string.h"
33 #include "be_structure.h"
34 #include "be_field.h"
35 #include "be_union.h"
36 #include "be_union_branch.h"
37 #include "be_typedef.h"
38 #include "be_helper.h"
39 #include "be_extern.h"
40 #include "utl_identifier.h"
41 #include "idl_defines.h"
42 #include "nr_extern.h"
43 #include "ace/Log_Msg.h"
45 #include <string>
47 be_visitor_arg_traits::be_visitor_arg_traits (const char *S,
48 be_visitor_context *ctx)
49 : be_visitor_scope (ctx),
50 S_ (ACE::strnew (S))
54 be_visitor_arg_traits::~be_visitor_arg_traits ()
56 delete [] this->S_;
59 int
60 be_visitor_arg_traits::visit_root (be_root *node)
62 TAO_OutStream *os = this->ctx_->stream ();
64 TAO_INSERT_COMMENT (os);
66 *os << be_nl
67 << be_global->core_versioning_begin ();
69 *os << be_nl_2
70 << "// Arg traits specializations." << be_nl
71 << "namespace TAO" << be_nl
72 << "{" << be_idt;
74 if (be_global->ami_call_back ())
76 int const status =
77 this->visit_valuetype (be_global->messaging_exceptionholder ());
79 if (-1 == status)
81 ACE_ERROR_RETURN ((LM_ERROR,
82 "(%N:%l) be_visitor_arg_traits::"
83 "visit_root - visit "
84 "Messaging::ExceptionHolder failed\n"),
85 -1);
89 if (this->visit_scope (node) == -1)
91 ACE_ERROR_RETURN ((LM_ERROR,
92 "(%N:%l) be_visitor_arg_traits::"
93 "visit_root - visit scope failed\n"),
94 -1);
97 *os << be_uidt_nl
98 << "}" << be_nl;
100 *os << be_global->core_versioning_end () << be_nl;
102 return 0;
106 be_visitor_arg_traits::visit_module (be_module *node)
108 if (this->visit_scope (node) == -1)
110 ACE_ERROR_RETURN ((LM_ERROR,
111 "(%N:%l) be_visitor_arg_traits::"
112 "visit_module - visit scope failed\n"),
113 -1);
116 return 0;
120 be_visitor_arg_traits::visit_interface (be_interface *node)
122 if (node->imported ())
124 // Arg traits will presumably already be generated, but
125 // perhaps from another compilation unit. We mark it
126 // generated because if we get here from a typedef in
127 // the main file, we should skip it.
128 this->generated (node, true);
129 return 0;
132 // A local interface can never be an argument.
133 if (node->is_local () || this->generated (node))
135 return 0;
138 this->generated (node, true);
140 TAO_OutStream *os = this->ctx_->stream ();
142 TAO_INSERT_COMMENT (os);
144 std::string guard_suffix =
145 std::string (this->S_) + std::string ("arg_traits");
147 // The guard should be generated to prevent multiple declarations,
148 // since a forward declaration may appear more than once.
149 os->gen_ifdef_macro (node->flat_name (), guard_suffix.c_str (), false);
151 *os << be_nl_2
152 << "template<>" << be_nl
153 << "class "
154 << " " << this->S_ << "Arg_Traits< ::"
155 << node->name () << ">" << be_idt_nl
156 << ": public "
157 << "Object_" << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl
158 << "::" << node->name () << "_ptr," << be_nl
159 << "::" << node->name () << "_var," << be_nl
160 << "::" << node->name () << "_out";
162 if (ACE_OS::strlen (this->S_) == 0)
164 *os << "," << be_nl
165 << "TAO::Objref_Traits<" << node->name () << ">";
168 *os << "," << be_nl << this->insert_policy ()
169 << ">" << be_uidt << be_uidt << be_uidt_nl
170 << "{" << be_nl
171 << "};";
173 os->gen_endif ();
175 if (this->visit_scope (node) != 0)
177 ACE_ERROR_RETURN ((LM_ERROR,
178 "(%N:%l) be_visitor_arg_traits::"
179 "visit_interface - visit scope failed\n"),
180 -1);
183 return 0;
187 be_visitor_arg_traits::visit_interface_fwd (be_interface_fwd *node)
189 if (node->imported ())
191 // Arg traits will presumably already be generated, but
192 // perhaps from another compilation unit. We mark it
193 // generated because if we get here from a typedef in
194 // the main file, we should skip it.
195 this->generated (node, true);
196 return 0;
199 // If a full definition with the same name in the same scope
200 // has been seen, then it will have gone through visit_interface()
201 // already.
202 if (this->generated (node))
204 return 0;
207 be_interface *fd =
208 dynamic_cast<be_interface*> (node->full_definition ());
210 // The logic in visit_interface() should handle what gets generated
211 // and what doesn't.
212 if (this->visit_interface (fd) != 0)
214 ACE_ERROR_RETURN ((LM_ERROR,
215 "(%N:%l) be_visitor_arg_traits::"
216 "visit_interface_fwd - code generation failed\n"),
217 -1);
220 this->generated (node, true);
221 return 0;
225 be_visitor_arg_traits::visit_valuebox (be_valuebox *node)
227 if (node->imported ())
229 // Arg traits will presumably already be generated, but
230 // perhaps from another compilation unit. We mark it
231 // generated because if we get here from a typedef in
232 // the main file, we should skip it.
233 this->generated (node, true);
234 return 0;
237 if (this->generated (node))
239 return 0;
242 TAO_OutStream & os = *this->ctx_->stream ();
244 TAO_INSERT_COMMENT (&os);
246 os << be_nl_2
247 << "template<>" << be_nl
248 << "class "
249 << this->S_ << "Arg_Traits< ::"
250 << node->name () << ">" << be_idt_nl
251 << ": public" << be_idt << be_idt_nl
252 << "Object_" << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl
253 << "::" << node->name () << " *," << be_nl
254 << "::" << node->name () << "_var," << be_nl
255 << "::" << node->name () << "_out";
257 // The SArgument classes don't need the traits parameter (yet?)
258 if (ACE_OS::strlen (this->S_) == 0)
260 os << "," << be_nl
261 << "TAO::Value_Traits<" << node->name () << ">";
264 os << "," << be_nl << this->insert_policy()
265 << be_uidt_nl
266 << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl
267 << "{" << be_nl
268 << "};";
270 this->generated (node, true);
271 return 0;
275 be_visitor_arg_traits::visit_valuetype (be_valuetype *node)
277 if (node->imported ())
279 // Arg traits will presumably already be generated, but
280 // perhaps from another compilation unit. We mark it
281 // generated because if we get here from a typedef in
282 // the main file, we should skip it.
283 this->generated (node, true);
284 return 0;
287 if (this->generated (node))
289 return 0;
292 /// Put this here to prevent infinite recursion with recursive
293 /// valuetypes.
294 this->generated (node, true);
296 TAO_OutStream & os = *this->ctx_->stream ();
298 TAO_INSERT_COMMENT (&os);
300 std::string guard_suffix =
301 std::string (this->S_) + std::string ("arg_traits");
303 // The guard should be generated to prevent multiple declarations,
304 // since a forward declaration may appear more than once.
305 os.gen_ifdef_macro (node->flat_name (), guard_suffix.c_str (), false);
307 os << be_nl_2
308 << "template<>" << be_nl
309 << "class "
310 << this->S_ << "Arg_Traits< ::"
311 << node->name () << ">" << be_idt_nl
312 << ": public" << be_idt << be_idt_nl
313 << "Object_" << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl
314 << "::" << node->name () << " *," << be_nl
315 << "::" << node->name () << "_var," << be_nl
316 << "::" << node->name () << "_out";
318 // The SArgument classes don't need the traits parameter (yet?)
319 if (ACE_OS::strlen (this->S_) == 0)
321 os << "," << be_nl
322 << "TAO::Value_Traits<" << node->name () << ">";
325 os << "," << be_nl << this->insert_policy()
326 << be_uidt_nl
327 << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl
328 << "{" << be_nl
329 << "};";
331 os.gen_endif ();
333 if (this->visit_scope (node) != 0)
335 ACE_ERROR_RETURN ((LM_ERROR,
336 "(%N:%l) be_visitor_arg_traits::"
337 "visit_valuetype - visit scope failed\n"),
338 -1);
341 return 0;
345 be_visitor_arg_traits::visit_valuetype_fwd (be_valuetype_fwd *node)
347 if (node->imported ())
349 // Arg traits will presumably already be generated, but
350 // perhaps from another compilation unit. We mark it
351 // generated because if we get here from a typedef in
352 // the main file, we should skip it.
353 this->generated (node, true);
354 return 0;
357 if (this->generated (node))
359 return 0;
362 be_valuetype *fd =
363 dynamic_cast<be_valuetype*> (node->full_definition ());
365 // The logic in visit_valuetype() should handle what gets generated
366 // and what doesn't.
367 int status = this->visit_valuetype (fd);
369 if (status != 0)
371 ACE_ERROR_RETURN ((LM_ERROR,
372 "(%N:%l) be_visitor_arg_traits::"
373 "visit_valuetype_fwd - code generation failed\n"),
374 -1);
377 this->generated (node, true);
378 return 0;
382 be_visitor_arg_traits::visit_eventtype (be_eventtype *node)
384 return this->visit_valuetype (node);
388 be_visitor_arg_traits::visit_eventtype_fwd (be_eventtype_fwd *node)
390 return this->visit_valuetype_fwd (node);
394 be_visitor_arg_traits::visit_operation (be_operation *node)
396 if (this->generated (node) || node->is_local () || node->imported ())
398 return 0;
401 AST_Type *rt = node->return_type ();
402 AST_Decl::NodeType nt = rt->node_type ();
404 // If our return type is an unaliased bounded (w)string, we create
405 // an empty struct using the operation's flat name for the type,
406 // and use this type as the Arg_Traits<> template parameter. All
407 // this is necessary because there could be any number of such
408 // return types, all identical, in the same interface, valuetype,
409 // translation unit, or build, and we need a unique type for the
410 // Arg_Traits<> template parameter.
411 if (nt == AST_Decl::NT_string || nt == AST_Decl::NT_wstring)
413 AST_String *str = dynamic_cast<AST_String*> (rt);
414 ACE_CDR::ULong bound = str->max_size ()->ev ()->u.ulval;
416 if (bound > 0)
418 TAO_OutStream *os = this->ctx_->stream ();
420 TAO_INSERT_COMMENT (os);
422 std::string guard_suffix =
423 std::string (this->S_) + std::string ("arg_traits");
425 // The guard should be generated to prevent multiple declarations,
426 // since a bounded (w)string of the same length may be used or typedef'd
427 // more than once.
429 os->gen_ifdef_macro (node->flat_name (), guard_suffix.c_str (), false);
431 bool wide = (str->width () != 1);
433 *os << be_nl_2;
435 // Avoid generating a duplicate structure in the skeleton.
436 if (ACE_OS::strlen (this->S_) == 0)
438 *os << "struct " << node->flat_name () << " {};"
439 << be_nl_2;
442 *os << "template<>" << be_nl
443 << "class "
444 << this->S_ << "Arg_Traits<"
445 << node->flat_name ()
446 << ">" << be_idt_nl
447 << ": public" << be_idt << be_idt_nl
448 << "BD_String_" << this->S_ << "Arg_Traits_T<" << be_nl
449 << "CORBA::" << (wide ? "W" : "") << "String_var," << be_nl
450 << bound << "," << be_nl
451 << this->insert_policy()
452 << ">"
453 << be_uidt << be_uidt << be_uidt_nl
454 << "{" << be_nl
455 << "};";
457 os->gen_endif ();
461 // This will catch (in visit_argument() below) any parameters that
462 // are unaliased, bounded (w)strings.
463 if (this->visit_scope (node) != 0)
465 ACE_ERROR_RETURN ((LM_ERROR,
466 ACE_TEXT ("be_visitor_arg_traits::")
467 ACE_TEXT ("visit_operation - visit scope failed\n")),
468 -1);
471 this->generated (node, true);
472 return 0;
476 be_visitor_arg_traits::visit_attribute (be_attribute *node)
478 if (this->ctx_->alias () != nullptr || this->generated (node))
480 return 0;
483 AST_String *st = dynamic_cast<AST_String*> (node->field_type ());
485 if (st == nullptr)
487 return 0;
490 ACE_CDR::ULong bound = st->max_size ()->ev ()->u.ulval;
492 if (bound == 0)
494 return 0;
497 TAO_OutStream *os = this->ctx_->stream ();
499 TAO_INSERT_COMMENT (os);
501 std::string guard_suffix =
502 std::string (this->S_) + std::string ("arg_traits");
504 // The guard should be generated to prevent multiple declarations,
505 // since a bounded (w)string of the same length may be used or typedef'd
506 // more than once.
508 os->gen_ifdef_macro (node->flat_name (), guard_suffix.c_str (), false);
510 bool wide = (st->width () != 1);
512 // It is legal IDL to declare a bounded (w)string as an operation
513 // parameter type. There could be any number of identical
514 // declarations in the same build, translation unit, or even in
515 // the same operation, so we use the argument's flat name to
516 // declare an empty struct, and use that struct as the template
517 // parameter for Arg_Traits<>.
519 *os << be_nl;
521 // Avoid generating a duplicate structure in the skeleton.
522 if (ACE_OS::strlen (this->S_) == 0)
524 *os << "struct " << node->flat_name () << " {};"
525 << be_nl_2;
528 *os << "template<>" << be_nl
529 << "class "
530 << this->S_ << "Arg_Traits<"
531 << node->flat_name ()
532 << ">" << be_idt_nl
533 << ": public" << be_idt << be_idt_nl
534 << "BD_String_" << this->S_ << "Arg_Traits_T<" << be_nl
535 << "CORBA::" << (wide ? "W" : "") << "String_var," << be_nl
536 << bound << "," << be_nl
537 << this->insert_policy()
538 << ">"
539 << be_uidt << be_uidt << be_uidt_nl
540 << "{" << be_nl
541 << "};";
543 os->gen_endif ();
545 this->generated (node, true);
546 return 0;
550 be_visitor_arg_traits::visit_argument (be_argument *node)
552 if (this->ctx_->alias () != nullptr || this->generated (node))
554 return 0;
557 AST_Type *bt = node->field_type ();
558 AST_Decl::NodeType nt = bt->node_type ();
560 // We are interested here only in unaliased, bounded
561 // (w)strings.
563 if (nt != AST_Decl::NT_string && nt != AST_Decl::NT_wstring)
565 return 0;
568 be_string *st = dynamic_cast<be_string*> (bt);
569 ACE_CDR::ULong bound = st->max_size ()->ev ()->u.ulval;
571 if (bound == 0)
573 return 0;
576 TAO_OutStream *os = this->ctx_->stream ();
578 TAO_INSERT_COMMENT (os);
580 std::string guard_suffix =
581 std::string (this->S_) + std::string ("arg_traits");
583 // The guard should be generated to prevent multiple declarations,
584 // since a bounded (w)string of the same length may be used or typedef'd
585 // more than once.
587 os->gen_ifdef_macro (node->flat_name (), guard_suffix.c_str (), false);
589 bool wide = (st->width () != 1);
591 // It is legal IDL to declare a bounded (w)string as an operation
592 // parameter type. There could be any number of identical
593 // declarations in the same build, translation unit, or even in
594 // the same operation, so we use the argument's flat name to
595 // declare an empty struct, and use that struct as the template
596 // parameter for Arg_Traits<>.
597 *os << be_nl_2;
599 AST_Decl *op = ScopeAsDecl (node->defined_in ());
600 AST_Decl *intf = ScopeAsDecl (op->defined_in ());
601 ACE_CString arg_flat_name (intf->flat_name ());
602 arg_flat_name += '_';
603 arg_flat_name += op->local_name ()->get_string ();
604 arg_flat_name += '_';
605 arg_flat_name += node->local_name ()->get_string ();
607 // Avoid generating a duplicate structure in the skeleton.
608 if (ACE_OS::strlen (this->S_) == 0)
610 *os << "struct " << arg_flat_name.c_str () << " {};"
611 << be_nl_2;
614 *os << "template<>" << be_nl
615 << "class "
616 << this->S_ << "Arg_Traits<"
617 << arg_flat_name.c_str ()
618 << ">" << be_idt_nl
619 << ": public" << be_idt << be_idt_nl
620 << "BD_String_" << this->S_ << "Arg_Traits_T<" << be_nl
621 << "CORBA::" << (wide ? "W" : "") << "String_var," << be_nl
622 << bound << "," << be_nl
623 << this->insert_policy()
624 << be_uidt_nl
625 << ">"
626 << be_uidt << be_uidt << be_uidt_nl
627 << "{" << be_nl
628 << "};";
630 os->gen_endif ();
632 this->generated (node, true);
633 return 0;
637 be_visitor_arg_traits::visit_sequence (be_sequence *node)
639 if (node->imported ())
641 // Arg traits will presumably already be generated, but
642 // perhaps from another compilation unit. We mark it
643 // generated because if we get here from a typedef in
644 // the main file, we should skip it.
645 this->generated (node, true);
646 return 0;
649 if (idl_global->dcps_sequence_type_defined (node->full_name ()))
651 this->generated (node, true);
652 return 0;
655 if (this->generated (node))
657 return 0;
660 this->generated (node, true);
662 TAO_OutStream *os = this->ctx_->stream ();
663 be_typedef *alias = this->ctx_->alias ();
665 /// No arg traits for anonymous sequences.
666 if (alias == nullptr)
668 return 0;
671 TAO_INSERT_COMMENT (os);
673 bool use_vec = (node->unbounded () && be_global->alt_mapping ());
674 UTL_ScopedName *sn = alias->name ();
676 *os << be_nl_2
677 << "template<>" << be_nl
678 << "class " << this->S_ << "Arg_Traits< ::" << sn << ">"
679 << be_idt_nl
680 << ": public" << be_idt << be_idt_nl
681 << (use_vec ? "Vector_" : "Var_Size_")
682 << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl
683 << "::" << sn << "," << be_nl
684 << this->insert_policy () << be_uidt_nl
685 << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl
686 << "{" << be_nl
687 << "};";
689 return 0;
693 be_visitor_arg_traits::visit_string (be_string *node)
695 if (node->imported ())
697 // Arg traits will presumably already be generated, but
698 // perhaps from another compilation unit. We mark it
699 // generated because if we get here from a typedef in
700 // the main file, we should skip it.
701 this->generated (node, true);
702 return 0;
705 if (this->generated (node) && !this->ctx_->alias())
707 return 0;
710 ACE_CDR::ULong bound = node->max_size ()->ev ()->u.ulval;
711 be_type *alias = this->ctx_->alias ();
713 // Unbounded (w)string args are handled as a predefined type.
714 // Bounded (w)strings must come in as a typedef - they can't
715 // be used directly as arguments or return types.
716 if (bound == 0)
718 return 0;
721 bool wide = (node->width () != 1);
723 TAO_OutStream *os = this->ctx_->stream ();
725 std::string guard_suffix =
726 std::string (this->S_) + std::string ("arg_traits");
728 // The guard should be generated to prevent multiple declarations,
729 // since a bounded (w)string of the same length may be used or typedef'd
730 // more than once.
732 if (alias == nullptr)
734 os->gen_ifdef_macro (node->flat_name (), guard_suffix.c_str (), false);
736 else
738 // Form a unique macro name using the local name and the bound.
739 ACE_CDR::ULong l = bound;
740 int num_digits = 0;
742 while (l > 0)
744 l /= 10 ;
745 ++num_digits ;
748 size_t bound_length = num_digits + 1;
749 char* bound_string = nullptr;
750 ACE_NEW_RETURN (bound_string, char[bound_length], -1) ;
751 ACE_OS::sprintf (bound_string, ACE_UINT32_FORMAT_SPECIFIER_ASCII, bound);
753 size_t cat_length = ACE_OS::strlen (alias->local_name ()->get_string ()) +
754 ACE_OS::strlen (bound_string) +
756 char* cat_string = nullptr;
757 ACE_NEW_RETURN (cat_string, char[cat_length], -1) ;
758 ACE_OS::strcpy (cat_string, alias->local_name ()->get_string ()) ;
759 ACE_OS::strcat (cat_string, bound_string);
761 os->gen_ifdef_macro (cat_string, guard_suffix.c_str (), false);
763 delete [] cat_string;
764 delete [] bound_string;
767 // Avoid generating a duplicate structure in the skeleton since
768 // it has already been generated in *C.h.
769 if (ACE_OS::strlen (this->S_) == 0)
771 // A workaround 'dummy' type, since bounded (w)strings are all
772 // generated as typedefs of (w)char *.
773 *os << be_nl_2
774 << "struct ";
776 if (alias == nullptr)
778 *os << node->flat_name ();
780 else
782 *os << alias->local_name () << "_" << bound;
785 *os << " {};";
788 *os << be_nl_2
789 << "template<>" << be_nl
790 << "class "
791 << this->S_ << "Arg_Traits<";
793 if (nullptr == alias)
795 *os << node->flat_name ();
797 else
799 *os << alias->local_name () << "_" << bound;
802 *os << ">" << be_idt_nl
803 << ": public" << be_idt << be_idt_nl
804 << "BD_String_" << this->S_ << "Arg_Traits_T<"
805 << be_idt << be_idt_nl
806 << "CORBA::" << (wide ? "W" : "") << "String_var," << be_nl
807 << bound << "," << be_nl
808 << this->insert_policy()
809 << be_uidt << be_uidt_nl
810 << ">"
811 << be_uidt << be_uidt << be_uidt_nl
812 << "{" << be_nl
813 << "};";
815 os->gen_endif ();
817 this->generated (node, true);
818 return 0;
822 be_visitor_arg_traits::visit_array (be_array *node)
824 if (node->imported ())
826 // Arg traits will presumably already be generated, but
827 // perhaps from another compilation unit. We mark it
828 // generated because if we get here from a typedef in
829 // the main file, we should skip it.
830 this->generated (node, true);
831 return 0;
834 // Add the alias check here because anonymous arrays can't be
835 // operation arguments.
836 if (this->generated (node) || this->ctx_->alias () == nullptr)
838 return 0;
841 TAO_OutStream *os = this->ctx_->stream ();
843 *os << be_nl_2
844 << "template<>" << be_nl
845 << "class "
846 << this->S_ << "Arg_Traits< ::"
847 << node->name () << "_tag>" << be_idt_nl
848 << ": public" << be_idt << be_idt_nl;
850 *os << (node->size_type () == AST_Type::FIXED ? "Fixed" : "Var")
851 << "_Array_" << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl
852 << "::" << node->name ()
853 << (node->size_type () == AST_Type::VARIABLE ? "_out" : "_var")
854 << "," << be_nl;
856 *os << "::" << node->name () << "_forany";
858 *os << "," << be_nl << this->insert_policy();
860 *os << be_uidt_nl
861 << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl
862 << "{" << be_nl
863 << "};";
865 this->generated (node, true);
866 return 0;
870 be_visitor_arg_traits::visit_enum (be_enum *node)
872 if (node->imported ())
874 // Arg traits will presumably already be generated, but
875 // perhaps from another compilation unit. We mark it
876 // generated because if we get here from a typedef in
877 // the main file, we should skip it.
878 this->generated (node, true);
879 return 0;
882 if (this->generated (node))
884 return 0;
887 TAO_OutStream *os = this->ctx_->stream ();
889 TAO_INSERT_COMMENT (os);
891 *os << be_nl_2
892 << "template<>" << be_nl
893 << "class "
894 << this->S_ << "Arg_Traits< ::"
895 << node->name () << ">" << be_idt_nl
896 << ": public" << be_idt << be_idt_nl;
898 *os << "Basic_" << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl
899 << "::" << node->name () << "," << be_nl
900 << this->insert_policy() << be_uidt_nl
901 << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl
902 << "{" << be_nl
903 << "};";
905 this->generated (node, true);
906 return 0;
910 be_visitor_arg_traits::visit_structure (be_structure *node)
912 if (node->imported ())
914 // Arg traits will presumably already be generated, but
915 // perhaps from another compilation unit. We mark it
916 // generated because if we get here from a typedef in
917 // the main file, we should skip it.
918 this->generated (node, true);
919 return 0;
922 if (this->generated (node))
924 return 0;
927 // This should be generated even for imported nodes. The ifdef guard prevents
928 // multiple declarations.
929 TAO_OutStream *os = this->ctx_->stream ();
931 TAO_INSERT_COMMENT (os);
933 *os << be_nl_2
934 << "template<>" << be_nl
935 << "class "
936 << this->S_ << "Arg_Traits< ::"
937 << node->name () << ">" << be_idt_nl
938 << ": public" << be_idt << be_idt_nl;
940 *os << (node->size_type () == AST_Type::FIXED ? "Fixed" : "Var")
941 << "_Size_" << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl;
943 *os << "::" << node->name () << "," << be_nl\
944 << this->insert_policy () << be_uidt_nl
945 << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl
946 << "{" << be_nl
947 << "};";
949 /* Set this before visiting the scope so things like
951 interface foo
953 struct bar
955 ....
956 foo foo_member;
959 void op (in bar inarg);
962 will not cause infinite recursion in this visitor.
965 this->generated (node, true);
967 if (this->visit_scope (node) != 0)
969 ACE_ERROR_RETURN ((LM_ERROR,
970 "(%N:%l) be_visitor_arg_traits::"
971 "visit_structure - visit scope failed\n"),
972 -1);
975 return 0;
979 be_visitor_arg_traits::visit_field (be_field *node)
981 be_type *bt = dynamic_cast<be_type*> (node->field_type ());
983 if (!bt)
985 ACE_ERROR_RETURN ((LM_ERROR,
986 "(%N:%l) be_visitor_arg_traits::"
987 "visit_field - "
988 "Bad field type\n"),
989 -1);
992 // Valuetypes may not be *declared* in a field, so this will
993 // get handled elsewhere, and will also avoid nested valuetype
994 // recursion. So we set the field node as processed (the
995 // field *type* may not have been reached yet) and return.
996 AST_Decl::NodeType nt = bt->base_node_type ();
998 if (nt == AST_Decl::NT_valuetype || nt == AST_Decl::NT_eventtype)
1000 node->cli_traits_gen (true);
1001 return 0;
1004 if (bt->accept (this) == -1)
1006 ACE_ERROR_RETURN ((LM_ERROR,
1007 "(%N:%l) be_visitor_arg_traits::"
1008 "visit_field - "
1009 "codegen for field type failed\n"),
1010 -1);
1013 this->generated (node, true);
1014 this->generated (bt, true);
1016 return 0;
1020 be_visitor_arg_traits::visit_union (be_union *node)
1022 if (node->imported ())
1024 // Arg traits will presumably already be generated, but
1025 // perhaps from another compilation unit. We mark it
1026 // generated because if we get here from a typedef in
1027 // the main file, we should skip it.
1028 this->generated (node, true);
1029 return 0;
1032 if (this->generated (node))
1034 return 0;
1037 // This should be generated even for imported nodes. The ifdef guard prevents
1038 // multiple declarations.
1039 TAO_OutStream *os = this->ctx_->stream ();
1041 TAO_INSERT_COMMENT (os);
1043 *os << be_nl_2
1044 << "template<>" << be_nl
1045 << "class "
1046 << this->S_ << "Arg_Traits< ::"
1047 << node->name () << ">" << be_idt_nl
1048 << ": public" << be_idt << be_idt_nl;
1050 *os << (node->size_type () == AST_Type::FIXED ? "Fixed" : "Var")
1051 << "_Size_" << this->S_ << "Arg_Traits_T<" << be_idt << be_idt_nl
1052 << "::" << node->name () << "," << be_nl
1053 << this->insert_policy ();
1055 *os << be_uidt_nl
1056 << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl
1057 << "{" << be_nl
1058 << "};";
1060 /* Set this before visiting the scope so things like
1062 interface foo
1064 struct bar
1066 ....
1067 foo foo_member;
1070 void op (in bar inarg);
1073 will not cause infinite recursion in this visitor.
1076 this->generated (node, true);
1078 int status = this->visit_scope (node);
1080 if (status != 0)
1082 ACE_ERROR_RETURN ((LM_ERROR,
1083 "(%N:%l) be_visitor_arg_traits::"
1084 "visit_union - visit scope failed\n"),
1085 -1);
1088 return 0;
1092 be_visitor_arg_traits::visit_union_branch (be_union_branch *node)
1094 be_type *bt = dynamic_cast<be_type*> (node->field_type ());
1096 if (!bt)
1098 ACE_ERROR_RETURN ((LM_ERROR,
1099 "(%N:%l) be_visitor_arg_traits::"
1100 "visit_union_branch - "
1101 "Bad union_branch type\n"),
1102 -1);
1105 if (bt->accept (this) == -1)
1107 ACE_ERROR_RETURN ((LM_ERROR,
1108 "(%N:%l) be_visitor_arg_traits::"
1109 "visit_union_branch - "
1110 "codegen for union_branch type failed\n"),
1111 -1);
1114 this->generated (node, true);
1115 return 0;
1119 be_visitor_arg_traits::visit_typedef (be_typedef *node)
1121 if (node->imported ())
1123 // Arg traits will presumably already be generated, but
1124 // perhaps from another compilation unit. We mark it
1125 // generated because if we get here from a typedef in
1126 // the main file, we should skip it.
1127 this->generated (node, true);
1128 return 0;
1131 if (this->generated (node))
1133 return 0;
1136 // Had to move up the spot where the typedef is marked as
1137 // having its arg traits instantiation already generated.
1138 // Consider the case where the base type is an interface,
1139 // the typedef occurs inside the interface, and the typdef
1140 // is used as an arg in an operation of a derived interface.
1141 // When the scope of the base interface is visited
1142 // as part of the arg traits visitation, we had infinite
1143 // recursion and a stack overflow.
1144 this->generated (node, true);
1146 this->ctx_->alias (node);
1148 // Make a decision based on the primitive base type.
1149 be_type *bt = node->primitive_base_type ();
1151 if (!bt || (bt->accept (this) == -1))
1153 ACE_ERROR_RETURN ((LM_ERROR,
1154 "(%N:%l) be_visitor_arg_traits::"
1155 "visit_typedef - "
1156 "Bad primitive type\n"),
1157 -1);
1160 this->ctx_->alias (nullptr);
1161 return 0;
1165 be_visitor_arg_traits::visit_component (be_component *node)
1167 return this->visit_interface (node);
1171 be_visitor_arg_traits::visit_component_fwd (be_component_fwd *node)
1173 return this->visit_interface_fwd (node);
1177 be_visitor_arg_traits::visit_connector (be_connector *node)
1179 return this->visit_component (node);
1183 be_visitor_arg_traits::visit_home (be_home *node)
1185 return this->visit_interface (node);
1188 bool
1189 be_visitor_arg_traits::generated (be_decl *node) const
1191 if (ACE_OS::strcmp (this->S_, "") == 0)
1193 switch (this->ctx_->state ())
1195 case TAO_CodeGen::TAO_ROOT_CH:
1196 return node->cli_arg_traits_gen ();
1197 case TAO_CodeGen::TAO_ROOT_SH:
1198 return node->srv_arg_traits_gen ();
1199 default:
1200 return false;
1204 return node->srv_sarg_traits_gen ();
1207 void
1208 be_visitor_arg_traits::generated (be_decl *node,
1209 bool val)
1211 if (ACE_OS::strcmp (this->S_, "") == 0)
1213 switch (this->ctx_->state ())
1215 case TAO_CodeGen::TAO_ROOT_CH:
1216 node->cli_arg_traits_gen (val);
1217 return;
1218 case TAO_CodeGen::TAO_ROOT_SH:
1219 node->srv_arg_traits_gen (val);
1220 return;
1221 default:
1222 return;
1226 node->srv_sarg_traits_gen (val);
1229 const char *
1230 be_visitor_arg_traits::insert_policy ()
1232 if (be_global->any_support ())
1234 if (be_global->gen_anytypecode_adapter ())
1236 return "TAO::Any_Insert_Policy_AnyTypeCode_Adapter";
1238 else
1240 return "TAO::Any_Insert_Policy_Stream";
1243 else
1245 return "TAO::Any_Insert_Policy_Noop";