1 //=============================================================================
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>
9 //=============================================================================
11 #include "be_visitor_arg_traits.h"
12 #include "be_visitor_context.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"
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"
30 #include "be_predefined_type.h"
31 #include "be_sequence.h"
32 #include "be_string.h"
33 #include "be_structure.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"
47 be_visitor_arg_traits::be_visitor_arg_traits (const char *S
,
48 be_visitor_context
*ctx
)
49 : be_visitor_scope (ctx
),
54 be_visitor_arg_traits::~be_visitor_arg_traits (void)
60 be_visitor_arg_traits::visit_root (be_root
*node
)
62 TAO_OutStream
*os
= this->ctx_
->stream ();
64 TAO_INSERT_COMMENT (os
);
67 << be_global
->core_versioning_begin ();
70 << "// Arg traits specializations." << be_nl
71 << "namespace TAO" << be_nl
74 if (be_global
->ami_call_back ())
77 this->visit_valuetype (be_global
->messaging_exceptionholder ());
81 ACE_ERROR_RETURN ((LM_ERROR
,
82 "(%N:%l) be_visitor_arg_traits::"
84 "Messaging::ExceptionHolder failed\n"),
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"),
100 *os
<< be_global
->core_versioning_end () << be_nl
;
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"),
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);
132 // A local interface can never be an argument.
133 if (node
->is_local () || this->generated (node
))
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);
152 << "template<>" << be_nl
154 << " " << this->S_
<< "Arg_Traits< ::"
155 << node
->name () << ">" << be_idt_nl
156 << ": public" << be_idt
<< be_idt_nl
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)
165 << "TAO::Objref_Traits<" << node
->name () << ">";
168 *os
<< "," << be_nl
<< this->insert_policy ()
170 << ">" << be_uidt
<< be_uidt
<< be_uidt
<< be_uidt_nl
176 if (this->visit_scope (node
) != 0)
178 ACE_ERROR_RETURN ((LM_ERROR
,
179 "(%N:%l) be_visitor_arg_traits::"
180 "visit_interface - visit scope failed\n"),
188 be_visitor_arg_traits::visit_interface_fwd (be_interface_fwd
*node
)
190 if (node
->imported ())
192 // Arg traits will presumably already be generated, but
193 // perhaps from another compilation unit. We mark it
194 // generated because if we get here from a typedef in
195 // the main file, we should skip it.
196 this->generated (node
, true);
200 // If a full definition with the same name in the same scope
201 // has been seen, then it will have gone through visit_interface()
203 if (this->generated (node
))
209 dynamic_cast<be_interface
*> (node
->full_definition ());
211 // The logic in visit_interface() should handle what gets generated
213 if (this->visit_interface (fd
) != 0)
215 ACE_ERROR_RETURN ((LM_ERROR
,
216 "(%N:%l) be_visitor_arg_traits::"
217 "visit_interface_fwd - code generation failed\n"),
221 this->generated (node
, true);
226 be_visitor_arg_traits::visit_valuebox (be_valuebox
*node
)
228 if (node
->imported ())
230 // Arg traits will presumably already be generated, but
231 // perhaps from another compilation unit. We mark it
232 // generated because if we get here from a typedef in
233 // the main file, we should skip it.
234 this->generated (node
, true);
238 if (this->generated (node
))
243 TAO_OutStream
& os
= *this->ctx_
->stream ();
245 TAO_INSERT_COMMENT (&os
);
248 << "template<>" << be_nl
250 << this->S_
<< "Arg_Traits< ::"
251 << node
->name () << ">" << be_idt_nl
252 << ": public" << be_idt
<< be_idt_nl
253 << "Object_" << this->S_
<< "Arg_Traits_T<" << be_idt
<< be_idt_nl
254 << "::" << node
->name () << " *," << be_nl
255 << "::" << node
->name () << "_var," << be_nl
256 << "::" << node
->name () << "_out";
258 // The SArgument classes don't need the traits parameter (yet?)
259 if (ACE_OS::strlen (this->S_
) == 0)
262 << "TAO::Value_Traits<" << node
->name () << ">";
265 os
<< "," << be_nl
<< this->insert_policy()
267 << ">" << be_uidt
<< be_uidt
<< be_uidt
<< be_uidt_nl
271 this->generated (node
, true);
276 be_visitor_arg_traits::visit_valuetype (be_valuetype
*node
)
278 if (node
->imported ())
280 // Arg traits will presumably already be generated, but
281 // perhaps from another compilation unit. We mark it
282 // generated because if we get here from a typedef in
283 // the main file, we should skip it.
284 this->generated (node
, true);
288 if (this->generated (node
))
293 /// Put this here to prevent infinite recursion with recursive
295 this->generated (node
, true);
297 TAO_OutStream
& os
= *this->ctx_
->stream ();
299 TAO_INSERT_COMMENT (&os
);
301 std::string guard_suffix
=
302 std::string (this->S_
) + std::string ("arg_traits");
304 // The guard should be generated to prevent multiple declarations,
305 // since a forward declaration may appear more than once.
306 os
.gen_ifdef_macro (node
->flat_name (), guard_suffix
.c_str (), false);
309 << "template<>" << be_nl
311 << this->S_
<< "Arg_Traits< ::"
312 << node
->name () << ">" << be_idt_nl
313 << ": public" << be_idt
<< be_idt_nl
314 << "Object_" << this->S_
<< "Arg_Traits_T<" << be_idt
<< be_idt_nl
315 << "::" << node
->name () << " *," << be_nl
316 << "::" << node
->name () << "_var," << be_nl
317 << "::" << node
->name () << "_out";
319 // The SArgument classes don't need the traits parameter (yet?)
320 if (ACE_OS::strlen (this->S_
) == 0)
323 << "TAO::Value_Traits<" << node
->name () << ">";
326 os
<< "," << be_nl
<< this->insert_policy()
328 << ">" << be_uidt
<< be_uidt
<< be_uidt
<< be_uidt_nl
334 if (this->visit_scope (node
) != 0)
336 ACE_ERROR_RETURN ((LM_ERROR
,
337 "(%N:%l) be_visitor_arg_traits::"
338 "visit_valuetype - visit scope failed\n"),
346 be_visitor_arg_traits::visit_valuetype_fwd (be_valuetype_fwd
*node
)
348 if (node
->imported ())
350 // Arg traits will presumably already be generated, but
351 // perhaps from another compilation unit. We mark it
352 // generated because if we get here from a typedef in
353 // the main file, we should skip it.
354 this->generated (node
, true);
358 if (this->generated (node
))
364 dynamic_cast<be_valuetype
*> (node
->full_definition ());
366 // The logic in visit_valuetype() should handle what gets generated
368 int status
= this->visit_valuetype (fd
);
372 ACE_ERROR_RETURN ((LM_ERROR
,
373 "(%N:%l) be_visitor_arg_traits::"
374 "visit_valuetype_fwd - code generation failed\n"),
378 this->generated (node
, true);
383 be_visitor_arg_traits::visit_eventtype (be_eventtype
*node
)
385 return this->visit_valuetype (node
);
389 be_visitor_arg_traits::visit_eventtype_fwd (be_eventtype_fwd
*node
)
391 return this->visit_valuetype_fwd (node
);
395 be_visitor_arg_traits::visit_operation (be_operation
*node
)
397 if (this->generated (node
) || node
->is_local () || node
->imported ())
402 AST_Type
*rt
= node
->return_type ();
403 AST_Decl::NodeType nt
= rt
->node_type ();
405 // If our return type is an unaliased bounded (w)string, we create
406 // an empty struct using the operation's flat name for the type,
407 // and use this type as the Arg_Traits<> template parameter. All
408 // this is necessary because there could be any number of such
409 // return types, all identical, in the same interface, valuetype,
410 // translation unit, or build, and we need a unique type for the
411 // Arg_Traits<> template parameter.
412 if (nt
== AST_Decl::NT_string
|| nt
== AST_Decl::NT_wstring
)
414 AST_String
*str
= dynamic_cast<AST_String
*> (rt
);
415 ACE_CDR::ULong bound
= str
->max_size ()->ev ()->u
.ulval
;
419 TAO_OutStream
*os
= this->ctx_
->stream ();
421 TAO_INSERT_COMMENT (os
);
423 std::string guard_suffix
=
424 std::string (this->S_
) + std::string ("arg_traits");
426 // The guard should be generated to prevent multiple declarations,
427 // since a bounded (w)string of the same length may be used or typedef'd
430 os
->gen_ifdef_macro (node
->flat_name (), guard_suffix
.c_str (), false);
432 bool wide
= (str
->width () != 1);
436 // Avoid generating a duplicate structure in the skeleton.
437 if (ACE_OS::strlen (this->S_
) == 0)
439 *os
<< "struct " << node
->flat_name () << " {};"
443 *os
<< "template<>" << be_nl
445 << this->S_
<< "Arg_Traits<"
446 << node
->flat_name ()
448 << ": public" << be_idt
<< be_idt_nl
449 << "BD_String_" << this->S_
<< "Arg_Traits_T<" << be_nl
450 << "CORBA::" << (wide
? "W" : "") << "String_var," << be_nl
451 << bound
<< "," << be_nl
452 << this->insert_policy()
454 << be_uidt
<< be_uidt
<< be_uidt_nl
462 // This will catch (in visit_argument() below) any parameters that
463 // are unaliased, bounded (w)strings.
464 if (this->visit_scope (node
) != 0)
466 ACE_ERROR_RETURN ((LM_ERROR
,
467 ACE_TEXT ("be_visitor_arg_traits::")
468 ACE_TEXT ("visit_operation - visit scope failed\n")),
472 this->generated (node
, true);
477 be_visitor_arg_traits::visit_attribute (be_attribute
*node
)
479 if (this->ctx_
->alias () != 0 || this->generated (node
))
484 AST_String
*st
= dynamic_cast<AST_String
*> (node
->field_type ());
491 ACE_CDR::ULong bound
= st
->max_size ()->ev ()->u
.ulval
;
498 TAO_OutStream
*os
= this->ctx_
->stream ();
500 TAO_INSERT_COMMENT (os
);
502 std::string guard_suffix
=
503 std::string (this->S_
) + std::string ("arg_traits");
505 // The guard should be generated to prevent multiple declarations,
506 // since a bounded (w)string of the same length may be used or typedef'd
509 os
->gen_ifdef_macro (node
->flat_name (), guard_suffix
.c_str (), false);
511 bool wide
= (st
->width () != 1);
513 // It is legal IDL to declare a bounded (w)string as an operation
514 // parameter type. There could be any number of identical
515 // declarations in the same build, translation unit, or even in
516 // the same operation, so we use the argument's flat name to
517 // declare an empty struct, and use that struct as the template
518 // parameter for Arg_Traits<>.
522 // Avoid generating a duplicate structure in the skeleton.
523 if (ACE_OS::strlen (this->S_
) == 0)
525 *os
<< "struct " << node
->flat_name () << " {};"
529 *os
<< "template<>" << be_nl
531 << this->S_
<< "Arg_Traits<"
532 << node
->flat_name ()
534 << ": public" << be_idt
<< be_idt_nl
535 << "BD_String_" << this->S_
<< "Arg_Traits_T<" << be_nl
536 << "CORBA::" << (wide
? "W" : "") << "String_var," << be_nl
537 << bound
<< "," << be_nl
538 << this->insert_policy()
540 << be_uidt
<< be_uidt
<< be_uidt_nl
546 this->generated (node
, true);
551 be_visitor_arg_traits::visit_argument (be_argument
*node
)
553 if (this->ctx_
->alias () != 0 || this->generated (node
))
558 AST_Type
*bt
= node
->field_type ();
559 AST_Decl::NodeType nt
= bt
->node_type ();
561 // We are interested here only in unaliased, bounded
564 if (nt
!= AST_Decl::NT_string
&& nt
!= AST_Decl::NT_wstring
)
569 be_string
*st
= dynamic_cast<be_string
*> (bt
);
570 ACE_CDR::ULong bound
= st
->max_size ()->ev ()->u
.ulval
;
577 TAO_OutStream
*os
= this->ctx_
->stream ();
579 TAO_INSERT_COMMENT (os
);
581 std::string guard_suffix
=
582 std::string (this->S_
) + std::string ("arg_traits");
584 // The guard should be generated to prevent multiple declarations,
585 // since a bounded (w)string of the same length may be used or typedef'd
588 os
->gen_ifdef_macro (node
->flat_name (), guard_suffix
.c_str (), false);
590 bool wide
= (st
->width () != 1);
592 // It is legal IDL to declare a bounded (w)string as an operation
593 // parameter type. There could be any number of identical
594 // declarations in the same build, translation unit, or even in
595 // the same operation, so we use the argument's flat name to
596 // declare an empty struct, and use that struct as the template
597 // parameter for Arg_Traits<>.
600 AST_Decl
*op
= ScopeAsDecl (node
->defined_in ());
601 AST_Decl
*intf
= ScopeAsDecl (op
->defined_in ());
602 ACE_CString
arg_flat_name (intf
->flat_name ());
603 arg_flat_name
+= '_';
604 arg_flat_name
+= op
->local_name ()->get_string ();
605 arg_flat_name
+= '_';
606 arg_flat_name
+= node
->local_name ()->get_string ();
608 // Avoid generating a duplicate structure in the skeleton.
609 if (ACE_OS::strlen (this->S_
) == 0)
611 *os
<< "struct " << arg_flat_name
.c_str () << " {};"
615 *os
<< "template<>" << be_nl
617 << this->S_
<< "Arg_Traits<"
618 << arg_flat_name
.c_str ()
620 << ": public" << be_idt
<< be_idt_nl
621 << "BD_String_" << this->S_
<< "Arg_Traits_T<" << be_nl
622 << "CORBA::" << (wide
? "W" : "") << "String_var," << be_nl
623 << bound
<< "," << be_nl
624 << this->insert_policy()
627 << be_uidt
<< be_uidt
<< be_uidt_nl
633 this->generated (node
, true);
638 be_visitor_arg_traits::visit_sequence (be_sequence
*node
)
640 if (node
->imported ())
642 // Arg traits will presumably already be generated, but
643 // perhaps from another compilation unit. We mark it
644 // generated because if we get here from a typedef in
645 // the main file, we should skip it.
646 this->generated (node
, true);
650 if (idl_global
->dcps_sequence_type_defined (node
->full_name ()))
652 this->generated (node
, true);
656 if (this->generated (node
))
661 this->generated (node
, true);
663 TAO_OutStream
*os
= this->ctx_
->stream ();
664 be_typedef
*alias
= this->ctx_
->alias ();
666 /// No arg traits for anonymous sequences.
672 TAO_INSERT_COMMENT (os
);
674 bool use_vec
= (node
->unbounded () && be_global
->alt_mapping ());
675 UTL_ScopedName
*sn
= alias
->name ();
678 << "template<>" << be_nl
679 << "class " << this->S_
<< "Arg_Traits< ::" << sn
<< ">"
681 << ": public" << be_idt
<< be_idt_nl
682 << (use_vec
? "Vector_" : "Var_Size_")
683 << this->S_
<< "Arg_Traits_T<" << be_idt
<< be_idt_nl
684 << "::" << sn
<< "," << be_nl
685 << this->insert_policy () << be_uidt_nl
686 << ">" << be_uidt
<< be_uidt
<< be_uidt
<< be_uidt_nl
694 be_visitor_arg_traits::visit_string (be_string
*node
)
696 if (node
->imported ())
698 // Arg traits will presumably already be generated, but
699 // perhaps from another compilation unit. We mark it
700 // generated because if we get here from a typedef in
701 // the main file, we should skip it.
702 this->generated (node
, true);
706 if (this->generated (node
) && !this->ctx_
->alias())
711 ACE_CDR::ULong bound
= node
->max_size ()->ev ()->u
.ulval
;
712 be_type
*alias
= this->ctx_
->alias ();
714 // Unbounded (w)string args are handled as a predefined type.
715 // Bounded (w)strings must come in as a typedef - they can't
716 // be used directly as arguments or return types.
722 bool wide
= (node
->width () != 1);
724 TAO_OutStream
*os
= this->ctx_
->stream ();
726 std::string guard_suffix
=
727 std::string (this->S_
) + std::string ("arg_traits");
729 // The guard should be generated to prevent multiple declarations,
730 // since a bounded (w)string of the same length may be used or typedef'd
735 os
->gen_ifdef_macro (node
->flat_name (), guard_suffix
.c_str (), false);
739 // Form a unique macro name using the local name and the bound.
740 ACE_CDR::ULong l
= bound
;
749 size_t bound_length
= num_digits
+ 1;
750 char* bound_string
= 0;
751 ACE_NEW_RETURN (bound_string
, char[bound_length
], -1) ;
752 ACE_OS::sprintf (bound_string
, ACE_UINT32_FORMAT_SPECIFIER_ASCII
, bound
);
754 size_t cat_length
= ACE_OS::strlen (alias
->local_name ()->get_string ()) +
755 ACE_OS::strlen (bound_string
) +
757 char* cat_string
= 0;
758 ACE_NEW_RETURN (cat_string
, char[cat_length
], -1) ;
759 ACE_OS::strcpy (cat_string
, alias
->local_name ()->get_string ()) ;
760 ACE_OS::strcat (cat_string
, bound_string
);
762 os
->gen_ifdef_macro (cat_string
, guard_suffix
.c_str (), false);
764 delete [] cat_string
;
765 delete [] bound_string
;
768 // Avoid generating a duplicate structure in the skeleton since
769 // it has already been generated in *C.h.
770 if (ACE_OS::strlen (this->S_
) == 0)
772 // A workaround 'dummy' type, since bounded (w)strings are all
773 // generated as typedefs of (w)char *.
779 *os
<< node
->flat_name ();
783 *os
<< alias
->local_name () << "_" << bound
;
790 << "template<>" << be_nl
792 << this->S_
<< "Arg_Traits<";
796 *os
<< node
->flat_name ();
800 *os
<< alias
->local_name () << "_" << bound
;
803 *os
<< ">" << be_idt_nl
804 << ": public" << be_idt
<< be_idt_nl
805 << "BD_String_" << this->S_
<< "Arg_Traits_T<"
806 << be_idt
<< be_idt_nl
807 << "CORBA::" << (wide
? "W" : "") << "String_var," << be_nl
808 << bound
<< "," << be_nl
809 << this->insert_policy()
810 << be_uidt
<< be_uidt_nl
812 << be_uidt
<< be_uidt
<< be_uidt_nl
818 this->generated (node
, true);
823 be_visitor_arg_traits::visit_array (be_array
*node
)
825 if (node
->imported ())
827 // Arg traits will presumably already be generated, but
828 // perhaps from another compilation unit. We mark it
829 // generated because if we get here from a typedef in
830 // the main file, we should skip it.
831 this->generated (node
, true);
835 // Add the alias check here because anonymous arrays can't be
836 // operation arguments.
837 if (this->generated (node
) || this->ctx_
->alias () == 0)
842 TAO_OutStream
*os
= this->ctx_
->stream ();
845 << "template<>" << be_nl
847 << this->S_
<< "Arg_Traits< ::"
848 << node
->name () << "_tag>" << be_idt_nl
849 << ": public" << be_idt
<< be_idt_nl
;
851 *os
<< (node
->size_type () == AST_Type::FIXED
? "Fixed" : "Var")
852 << "_Array_" << this->S_
<< "Arg_Traits_T<" << be_idt
<< be_idt_nl
853 << "::" << node
->name ()
854 << (node
->size_type () == AST_Type::VARIABLE
? "_out" : "_var")
857 *os
<< "::" << node
->name () << "_forany";
859 *os
<< "," << be_nl
<< this->insert_policy();
862 << ">" << be_uidt
<< be_uidt
<< be_uidt
<< be_uidt_nl
866 this->generated (node
, true);
871 be_visitor_arg_traits::visit_enum (be_enum
*node
)
873 if (node
->imported ())
875 // Arg traits will presumably already be generated, but
876 // perhaps from another compilation unit. We mark it
877 // generated because if we get here from a typedef in
878 // the main file, we should skip it.
879 this->generated (node
, true);
883 if (this->generated (node
))
888 TAO_OutStream
*os
= this->ctx_
->stream ();
890 TAO_INSERT_COMMENT (os
);
893 << "template<>" << be_nl
895 << this->S_
<< "Arg_Traits< ::"
896 << node
->name () << ">" << be_idt_nl
897 << ": public" << be_idt
<< be_idt_nl
;
899 *os
<< "Basic_" << this->S_
<< "Arg_Traits_T<" << be_idt
<< be_idt_nl
900 << "::" << node
->name () << "," << be_nl
901 << this->insert_policy() << be_uidt_nl
902 << ">" << be_uidt
<< be_uidt
<< be_uidt
<< be_uidt_nl
906 this->generated (node
, true);
911 be_visitor_arg_traits::visit_structure (be_structure
*node
)
913 if (node
->imported ())
915 // Arg traits will presumably already be generated, but
916 // perhaps from another compilation unit. We mark it
917 // generated because if we get here from a typedef in
918 // the main file, we should skip it.
919 this->generated (node
, true);
923 if (this->generated (node
))
928 // This should be generated even for imported nodes. The ifdef guard prevents
929 // multiple declarations.
930 TAO_OutStream
*os
= this->ctx_
->stream ();
932 TAO_INSERT_COMMENT (os
);
935 << "template<>" << be_nl
937 << this->S_
<< "Arg_Traits< ::"
938 << node
->name () << ">" << be_idt_nl
939 << ": public" << be_idt
<< be_idt_nl
;
941 *os
<< (node
->size_type () == AST_Type::FIXED
? "Fixed" : "Var")
942 << "_Size_" << this->S_
<< "Arg_Traits_T<" << be_idt
<< be_idt_nl
;
944 *os
<< "::" << node
->name () << "," << be_nl\
945 << this->insert_policy () << be_uidt_nl
946 << ">" << be_uidt
<< be_uidt
<< be_uidt
<< be_uidt_nl
950 /* Set this before visiting the scope so things like
960 void op (in bar inarg);
963 will not cause infinite recursion in this visitor.
966 this->generated (node
, true);
968 if (this->visit_scope (node
) != 0)
970 ACE_ERROR_RETURN ((LM_ERROR
,
971 "(%N:%l) be_visitor_arg_traits::"
972 "visit_structure - visit scope failed\n"),
980 be_visitor_arg_traits::visit_field (be_field
*node
)
982 be_type
*bt
= dynamic_cast<be_type
*> (node
->field_type ());
986 ACE_ERROR_RETURN ((LM_ERROR
,
987 "(%N:%l) be_visitor_arg_traits::"
993 // Valuetypes may not be *declared* in a field, so this will
994 // get handled elsewhere, and will also avoid nested valuetype
995 // recursion. So we set the field node as processed (the
996 // field *type* may not have been reached yet) and return.
997 AST_Decl::NodeType nt
= bt
->base_node_type ();
999 if (nt
== AST_Decl::NT_valuetype
|| nt
== AST_Decl::NT_eventtype
)
1001 node
->cli_traits_gen (true);
1005 if (bt
->accept (this) == -1)
1007 ACE_ERROR_RETURN ((LM_ERROR
,
1008 "(%N:%l) be_visitor_arg_traits::"
1010 "codegen for field type failed\n"),
1014 this->generated (node
, true);
1015 this->generated (bt
, true);
1021 be_visitor_arg_traits::visit_union (be_union
*node
)
1023 if (node
->imported ())
1025 // Arg traits will presumably already be generated, but
1026 // perhaps from another compilation unit. We mark it
1027 // generated because if we get here from a typedef in
1028 // the main file, we should skip it.
1029 this->generated (node
, true);
1033 if (this->generated (node
))
1038 // This should be generated even for imported nodes. The ifdef guard prevents
1039 // multiple declarations.
1040 TAO_OutStream
*os
= this->ctx_
->stream ();
1042 TAO_INSERT_COMMENT (os
);
1045 << "template<>" << be_nl
1047 << this->S_
<< "Arg_Traits< ::"
1048 << node
->name () << ">" << be_idt_nl
1049 << ": public" << be_idt
<< be_idt_nl
;
1051 *os
<< (node
->size_type () == AST_Type::FIXED
? "Fixed" : "Var")
1052 << "_Size_" << this->S_
<< "Arg_Traits_T<" << be_idt
<< be_idt_nl
1053 << "::" << node
->name () << "," << be_nl
1054 << this->insert_policy ();
1057 << ">" << be_uidt
<< be_uidt
<< be_uidt
<< be_uidt_nl
1061 /* Set this before visiting the scope so things like
1071 void op (in bar inarg);
1074 will not cause infinite recursion in this visitor.
1077 this->generated (node
, true);
1079 int status
= this->visit_scope (node
);
1083 ACE_ERROR_RETURN ((LM_ERROR
,
1084 "(%N:%l) be_visitor_arg_traits::"
1085 "visit_union - visit scope failed\n"),
1093 be_visitor_arg_traits::visit_union_branch (be_union_branch
*node
)
1095 be_type
*bt
= dynamic_cast<be_type
*> (node
->field_type ());
1099 ACE_ERROR_RETURN ((LM_ERROR
,
1100 "(%N:%l) be_visitor_arg_traits::"
1101 "visit_union_branch - "
1102 "Bad union_branch type\n"),
1106 if (bt
->accept (this) == -1)
1108 ACE_ERROR_RETURN ((LM_ERROR
,
1109 "(%N:%l) be_visitor_arg_traits::"
1110 "visit_union_branch - "
1111 "codegen for union_branch type failed\n"),
1115 this->generated (node
, true);
1120 be_visitor_arg_traits::visit_typedef (be_typedef
*node
)
1122 if (node
->imported ())
1124 // Arg traits will presumably already be generated, but
1125 // perhaps from another compilation unit. We mark it
1126 // generated because if we get here from a typedef in
1127 // the main file, we should skip it.
1128 this->generated (node
, true);
1132 if (this->generated (node
))
1137 // Had to move up the spot where the typedef is marked as
1138 // having its arg traits instantiation already generated.
1139 // Consider the case where the base type is an interface,
1140 // the typedef occurs inside the interface, and the typdef
1141 // is used as an arg in an operation of a derived interface.
1142 // When the scope of the base interface is visited
1143 // as part of the arg traits visitation, we had infinite
1144 // recursion and a stack overflow.
1145 this->generated (node
, true);
1147 this->ctx_
->alias (node
);
1149 // Make a decision based on the primitive base type.
1150 be_type
*bt
= node
->primitive_base_type ();
1152 if (!bt
|| (bt
->accept (this) == -1))
1154 ACE_ERROR_RETURN ((LM_ERROR
,
1155 "(%N:%l) be_visitor_arg_traits::"
1157 "Bad primitive type\n"),
1161 this->ctx_
->alias (0);
1166 be_visitor_arg_traits::visit_component (be_component
*node
)
1168 return this->visit_interface (node
);
1172 be_visitor_arg_traits::visit_component_fwd (be_component_fwd
*node
)
1174 return this->visit_interface_fwd (node
);
1178 be_visitor_arg_traits::visit_connector (be_connector
*node
)
1180 return this->visit_component (node
);
1184 be_visitor_arg_traits::visit_home (be_home
*node
)
1186 return this->visit_interface (node
);
1190 be_visitor_arg_traits::generated (be_decl
*node
) const
1192 if (ACE_OS::strcmp (this->S_
, "") == 0)
1194 switch (this->ctx_
->state ())
1196 case TAO_CodeGen::TAO_ROOT_CH
:
1197 return node
->cli_arg_traits_gen ();
1198 case TAO_CodeGen::TAO_ROOT_SH
:
1199 return node
->srv_arg_traits_gen ();
1205 return node
->srv_sarg_traits_gen ();
1209 be_visitor_arg_traits::generated (be_decl
*node
,
1212 if (ACE_OS::strcmp (this->S_
, "") == 0)
1214 switch (this->ctx_
->state ())
1216 case TAO_CodeGen::TAO_ROOT_CH
:
1217 node
->cli_arg_traits_gen (val
);
1219 case TAO_CodeGen::TAO_ROOT_SH
:
1220 node
->srv_arg_traits_gen (val
);
1227 node
->srv_sarg_traits_gen (val
);
1231 be_visitor_arg_traits::insert_policy (void)
1233 if (be_global
->any_support ())
1235 if (be_global
->gen_anytypecode_adapter ())
1237 return "TAO::Any_Insert_Policy_AnyTypeCode_Adapter";
1241 return "TAO::Any_Insert_Policy_Stream";
1246 return "TAO::Any_Insert_Policy_Noop";