Merge pull request #1844 from jrw972/monterey
[ACE_TAO.git] / TAO / TAO_IDL / be / be_visitor_arg_traits.cpp
blob0b1ab3d5f9d777049b33bdb5f6054a5ae6295163
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 (void)
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" << 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)
164 *os << "," << be_nl
165 << "TAO::Objref_Traits<" << node->name () << ">";
168 *os << "," << be_nl << this->insert_policy ()
169 << be_uidt_nl
170 << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl
171 << "{" << be_nl
172 << "};";
174 os->gen_endif ();
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"),
181 -1);
184 return 0;
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);
197 return 0;
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()
202 // already.
203 if (this->generated (node))
205 return 0;
208 be_interface *fd =
209 dynamic_cast<be_interface*> (node->full_definition ());
211 // The logic in visit_interface() should handle what gets generated
212 // and what doesn't.
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"),
218 -1);
221 this->generated (node, true);
222 return 0;
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);
235 return 0;
238 if (this->generated (node))
240 return 0;
243 TAO_OutStream & os = *this->ctx_->stream ();
245 TAO_INSERT_COMMENT (&os);
247 os << be_nl_2
248 << "template<>" << be_nl
249 << "class "
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)
261 os << "," << be_nl
262 << "TAO::Value_Traits<" << node->name () << ">";
265 os << "," << be_nl << this->insert_policy()
266 << be_uidt_nl
267 << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl
268 << "{" << be_nl
269 << "};";
271 this->generated (node, true);
272 return 0;
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);
285 return 0;
288 if (this->generated (node))
290 return 0;
293 /// Put this here to prevent infinite recursion with recursive
294 /// valuetypes.
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);
308 os << be_nl_2
309 << "template<>" << be_nl
310 << "class "
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)
322 os << "," << be_nl
323 << "TAO::Value_Traits<" << node->name () << ">";
326 os << "," << be_nl << this->insert_policy()
327 << be_uidt_nl
328 << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl
329 << "{" << be_nl
330 << "};";
332 os.gen_endif ();
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"),
339 -1);
342 return 0;
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);
355 return 0;
358 if (this->generated (node))
360 return 0;
363 be_valuetype *fd =
364 dynamic_cast<be_valuetype*> (node->full_definition ());
366 // The logic in visit_valuetype() should handle what gets generated
367 // and what doesn't.
368 int status = this->visit_valuetype (fd);
370 if (status != 0)
372 ACE_ERROR_RETURN ((LM_ERROR,
373 "(%N:%l) be_visitor_arg_traits::"
374 "visit_valuetype_fwd - code generation failed\n"),
375 -1);
378 this->generated (node, true);
379 return 0;
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 ())
399 return 0;
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;
417 if (bound > 0)
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
428 // more than once.
430 os->gen_ifdef_macro (node->flat_name (), guard_suffix.c_str (), false);
432 bool wide = (str->width () != 1);
434 *os << be_nl_2;
436 // Avoid generating a duplicate structure in the skeleton.
437 if (ACE_OS::strlen (this->S_) == 0)
439 *os << "struct " << node->flat_name () << " {};"
440 << be_nl_2;
443 *os << "template<>" << be_nl
444 << "class "
445 << this->S_ << "Arg_Traits<"
446 << node->flat_name ()
447 << ">" << be_idt_nl
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()
453 << ">"
454 << be_uidt << be_uidt << be_uidt_nl
455 << "{" << be_nl
456 << "};";
458 os->gen_endif ();
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")),
469 -1);
472 this->generated (node, true);
473 return 0;
477 be_visitor_arg_traits::visit_attribute (be_attribute *node)
479 if (this->ctx_->alias () != 0 || this->generated (node))
481 return 0;
484 AST_String *st = dynamic_cast<AST_String*> (node->field_type ());
486 if (st == 0)
488 return 0;
491 ACE_CDR::ULong bound = st->max_size ()->ev ()->u.ulval;
493 if (bound == 0)
495 return 0;
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
507 // more than once.
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<>.
520 *os << be_nl;
522 // Avoid generating a duplicate structure in the skeleton.
523 if (ACE_OS::strlen (this->S_) == 0)
525 *os << "struct " << node->flat_name () << " {};"
526 << be_nl_2;
529 *os << "template<>" << be_nl
530 << "class "
531 << this->S_ << "Arg_Traits<"
532 << node->flat_name ()
533 << ">" << be_idt_nl
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()
539 << ">"
540 << be_uidt << be_uidt << be_uidt_nl
541 << "{" << be_nl
542 << "};";
544 os->gen_endif ();
546 this->generated (node, true);
547 return 0;
551 be_visitor_arg_traits::visit_argument (be_argument *node)
553 if (this->ctx_->alias () != 0 || this->generated (node))
555 return 0;
558 AST_Type *bt = node->field_type ();
559 AST_Decl::NodeType nt = bt->node_type ();
561 // We are interested here only in unaliased, bounded
562 // (w)strings.
564 if (nt != AST_Decl::NT_string && nt != AST_Decl::NT_wstring)
566 return 0;
569 be_string *st = dynamic_cast<be_string*> (bt);
570 ACE_CDR::ULong bound = st->max_size ()->ev ()->u.ulval;
572 if (bound == 0)
574 return 0;
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
586 // more than once.
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<>.
598 *os << be_nl_2;
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 () << " {};"
612 << be_nl_2;
615 *os << "template<>" << be_nl
616 << "class "
617 << this->S_ << "Arg_Traits<"
618 << arg_flat_name.c_str ()
619 << ">" << be_idt_nl
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()
625 << be_uidt_nl
626 << ">"
627 << be_uidt << be_uidt << be_uidt_nl
628 << "{" << be_nl
629 << "};";
631 os->gen_endif ();
633 this->generated (node, true);
634 return 0;
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);
647 return 0;
650 if (idl_global->dcps_sequence_type_defined (node->full_name ()))
652 this->generated (node, true);
653 return 0;
656 if (this->generated (node))
658 return 0;
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.
667 if (alias == 0)
669 return 0;
672 TAO_INSERT_COMMENT (os);
674 bool use_vec = (node->unbounded () && be_global->alt_mapping ());
675 UTL_ScopedName *sn = alias->name ();
677 *os << be_nl_2
678 << "template<>" << be_nl
679 << "class " << this->S_ << "Arg_Traits< ::" << sn << ">"
680 << be_idt_nl
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
687 << "{" << be_nl
688 << "};";
690 return 0;
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);
703 return 0;
706 if (this->generated (node) && !this->ctx_->alias())
708 return 0;
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.
717 if (bound == 0)
719 return 0;
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
731 // more than once.
733 if (alias == 0)
735 os->gen_ifdef_macro (node->flat_name (), guard_suffix.c_str (), false);
737 else
739 // Form a unique macro name using the local name and the bound.
740 ACE_CDR::ULong l = bound;
741 int num_digits = 0;
743 while (l > 0)
745 l /= 10 ;
746 ++num_digits ;
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 *.
774 *os << be_nl_2
775 << "struct ";
777 if (alias == 0)
779 *os << node->flat_name ();
781 else
783 *os << alias->local_name () << "_" << bound;
786 *os << " {};";
789 *os << be_nl_2
790 << "template<>" << be_nl
791 << "class "
792 << this->S_ << "Arg_Traits<";
794 if (0 == alias)
796 *os << node->flat_name ();
798 else
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
811 << ">"
812 << be_uidt << be_uidt << be_uidt_nl
813 << "{" << be_nl
814 << "};";
816 os->gen_endif ();
818 this->generated (node, true);
819 return 0;
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);
832 return 0;
835 // Add the alias check here because anonymous arrays can't be
836 // operation arguments.
837 if (this->generated (node) || this->ctx_->alias () == 0)
839 return 0;
842 TAO_OutStream *os = this->ctx_->stream ();
844 *os << be_nl_2
845 << "template<>" << be_nl
846 << "class "
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")
855 << "," << be_nl;
857 *os << "::" << node->name () << "_forany";
859 *os << "," << be_nl << this->insert_policy();
861 *os << be_uidt_nl
862 << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl
863 << "{" << be_nl
864 << "};";
866 this->generated (node, true);
867 return 0;
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);
880 return 0;
883 if (this->generated (node))
885 return 0;
888 TAO_OutStream *os = this->ctx_->stream ();
890 TAO_INSERT_COMMENT (os);
892 *os << be_nl_2
893 << "template<>" << be_nl
894 << "class "
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
903 << "{" << be_nl
904 << "};";
906 this->generated (node, true);
907 return 0;
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);
920 return 0;
923 if (this->generated (node))
925 return 0;
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);
934 *os << be_nl_2
935 << "template<>" << be_nl
936 << "class "
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
947 << "{" << be_nl
948 << "};";
950 /* Set this before visiting the scope so things like
952 interface foo
954 struct bar
956 ....
957 foo foo_member;
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"),
973 -1);
976 return 0;
980 be_visitor_arg_traits::visit_field (be_field *node)
982 be_type *bt = dynamic_cast<be_type*> (node->field_type ());
984 if (!bt)
986 ACE_ERROR_RETURN ((LM_ERROR,
987 "(%N:%l) be_visitor_arg_traits::"
988 "visit_field - "
989 "Bad field type\n"),
990 -1);
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);
1002 return 0;
1005 if (bt->accept (this) == -1)
1007 ACE_ERROR_RETURN ((LM_ERROR,
1008 "(%N:%l) be_visitor_arg_traits::"
1009 "visit_field - "
1010 "codegen for field type failed\n"),
1011 -1);
1014 this->generated (node, true);
1015 this->generated (bt, true);
1017 return 0;
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);
1030 return 0;
1033 if (this->generated (node))
1035 return 0;
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);
1044 *os << be_nl_2
1045 << "template<>" << be_nl
1046 << "class "
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 ();
1056 *os << be_uidt_nl
1057 << ">" << be_uidt << be_uidt << be_uidt << be_uidt_nl
1058 << "{" << be_nl
1059 << "};";
1061 /* Set this before visiting the scope so things like
1063 interface foo
1065 struct bar
1067 ....
1068 foo foo_member;
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);
1081 if (status != 0)
1083 ACE_ERROR_RETURN ((LM_ERROR,
1084 "(%N:%l) be_visitor_arg_traits::"
1085 "visit_union - visit scope failed\n"),
1086 -1);
1089 return 0;
1093 be_visitor_arg_traits::visit_union_branch (be_union_branch *node)
1095 be_type *bt = dynamic_cast<be_type*> (node->field_type ());
1097 if (!bt)
1099 ACE_ERROR_RETURN ((LM_ERROR,
1100 "(%N:%l) be_visitor_arg_traits::"
1101 "visit_union_branch - "
1102 "Bad union_branch type\n"),
1103 -1);
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"),
1112 -1);
1115 this->generated (node, true);
1116 return 0;
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);
1129 return 0;
1132 if (this->generated (node))
1134 return 0;
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::"
1156 "visit_typedef - "
1157 "Bad primitive type\n"),
1158 -1);
1161 this->ctx_->alias (0);
1162 return 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);
1189 bool
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 ();
1200 default:
1201 return 0;
1205 return node->srv_sarg_traits_gen ();
1208 void
1209 be_visitor_arg_traits::generated (be_decl *node,
1210 bool val)
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);
1218 return;
1219 case TAO_CodeGen::TAO_ROOT_SH:
1220 node->srv_arg_traits_gen (val);
1221 return;
1222 default:
1223 return;
1227 node->srv_sarg_traits_gen (val);
1230 const char *
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";
1239 else
1241 return "TAO::Any_Insert_Policy_Stream";
1244 else
1246 return "TAO::Any_Insert_Policy_Noop";