2 //=============================================================================
4 * @file valuebox_ch.cpp
6 * Visitor generating code for valueboxes in the client header
10 //=============================================================================
14 // ******************************************************
15 // Valuebox visitor for client header
16 // ******************************************************
18 be_visitor_valuebox_ch::be_visitor_valuebox_ch (be_visitor_context
*ctx
)
19 : be_visitor_valuebox (ctx
)
23 be_visitor_valuebox_ch::~be_visitor_valuebox_ch (void)
28 be_visitor_valuebox_ch::visit_valuebox (be_valuebox
*node
)
30 // Nothing to do if we are imported or code is already generated.
31 if (node
->cli_hdr_gen () || node
->imported ())
36 TAO_OutStream
*os
= this->ctx_
->stream ();
38 this->ctx_
->node (node
); // save the node
40 TAO_INSERT_COMMENT (os
);
43 << "class " << node
->local_name () << ";" ;
45 // Generate the _var and _out template class declarations.
47 << "typedef" << be_idt_nl
48 << "TAO_Value_Var_T<" << be_idt
<< be_idt_nl
49 << node
->local_name () << be_uidt_nl
51 << node
->local_name () << "_var;" << be_uidt_nl
<< be_nl
52 << "typedef" << be_idt_nl
53 << "TAO_Value_Out_T<" << be_idt
<< be_idt_nl
54 << node
->local_name () << be_uidt_nl
56 << node
->local_name () << "_out;" << be_uidt
;
58 *os
<< be_nl_2
<< "class " << be_global
->stub_export_macro ()
59 << " " << node
->local_name ();
60 *os
<< be_idt_nl
<<": public virtual ::CORBA::DefaultValueRefCountBase";
62 *os
<< be_uidt
<< be_nl
64 << "public:" << be_idt
;
66 node
->gen_stub_decls (os
);
70 << "static " << node
->local_name () << "* "
71 << "_downcast ( ::CORBA::ValueBase *);" << be_nl
;
74 *os
<< "::CORBA::ValueBase * _copy_value (void);" << be_nl_2
;
76 // repository id methods
77 *os
<< "virtual const char* "
78 << "_tao_obv_repository_id (void) const;"
81 << "_tao_obv_truncatable_repo_ids (Repository_Id_List &ids) const;"
83 << "static const char* "
84 << "_tao_obv_static_repository_id (void);" << be_nl_2
;
87 *os
<< "static ::CORBA::Boolean _tao_unmarshal (" << be_idt
<< be_idt_nl
88 << "TAO_InputCDR &," << be_nl
89 << node
->local_name () << " *&" << be_uidt_nl
90 << ");" << be_uidt_nl
<< be_nl
;
92 if (be_global
->tc_support ())
94 *os
<< "virtual ::CORBA::TypeCode_ptr _tao_type (void) const;"
98 be_type
*bt
= dynamic_cast<be_type
*> (node
->boxed_type ());
100 // Emit the type specific elements. The visit_* methods in this
101 // module do that work.
102 if (!bt
|| (bt
->accept (this) == -1))
104 ACE_ERROR_RETURN ((LM_ERROR
,
105 ACE_TEXT ("be_visitor_valuebox_ch::")
106 ACE_TEXT ("visit_valuebox - ")
107 ACE_TEXT ("type-specific valuebox")
108 ACE_TEXT (" code generation failed\n")),
112 TAO_INSERT_COMMENT (os
);
114 // Generate the "protected" destructor
116 *os
<< be_uidt_nl
<< be_nl
<< "protected:" << be_idt_nl
;
118 *os
<< "virtual ~" << node
->local_name () << " (void);" << be_nl
;
120 // Methods for marshalling and unmarshalling the value
121 *os
<< "virtual ::CORBA::Boolean "
122 << "_tao_marshal_v (TAO_OutputCDR &) const;" << be_nl
;
123 *os
<< "virtual ::CORBA::Boolean "
124 << "_tao_unmarshal_v (TAO_InputCDR &);" << be_nl
;
125 *os
<< "virtual ::CORBA::Boolean "
126 << "_tao_match_formal_type (ptrdiff_t ) const;" << be_nl
;
128 // Private unimplemented default assignment operator
129 *os
<< be_uidt_nl
<< "private:" << be_idt_nl
;
130 *os
<< "void operator= (const " << node
->local_name () << " & val);"
136 // Generate typecode declaration.
137 if (be_global
->tc_support ())
139 be_visitor_context
ctx (*this->ctx_
);
140 be_visitor_typecode_decl
visitor (&ctx
);
142 if (node
->accept (&visitor
) == -1)
144 ACE_ERROR_RETURN ((LM_ERROR
,
145 ACE_TEXT ("be_visitor_valuebox_ch::")
146 ACE_TEXT ("visit_valuebox - ")
147 ACE_TEXT ("TypeCode declaration failed\n")),
152 // Indicate that code is already generated for this node.
153 node
->cli_hdr_gen (true);
160 be_visitor_valuebox_ch::visit_array (be_array
*node
)
162 TAO_OutStream
*os
= this->ctx_
->stream ();
164 TAO_INSERT_COMMENT (os
);
166 this->emit_default_constructor();
168 // Public constructor that takes a const array argument
169 this->emit_constructor_one_arg (node
, "", "const ", "");
171 // Public copy constructor
172 this->emit_copy_constructor ();
174 *os
<< be_nl
<< "// assignment operator" << be_nl
;
176 // Public assignment operator that takes a const array argument
177 this->emit_assignment (node
, "", "const ", "");
179 // Public accessor and modifier methods
180 *os
<< "// Accessors and modifier" << be_nl
;
182 *os
<< "const " << node
->full_name () << "_slice* "
183 << "_value (void) const;" << be_nl
;
185 *os
<< node
->full_name () << "_slice* " << "_value (void);" << be_nl
;
187 *os
<< "void" << " _value (const " << node
->full_name () << " val);"
190 // Overloaded subscript operators
191 *os
<< "const " << node
->full_name ()
192 << "_slice & operator[] ( ::CORBA::ULong index) const;" << be_nl
;
194 *os
<< node
->full_name ()
195 << "_slice & operator[] ( ::CORBA::ULong index);"
198 // Explicit conversion functions
199 *os
<< "const " << node
->full_name ()
200 << "_slice * _boxed_in (void) const;"
203 *os
<< node
->full_name () << "_slice * _boxed_inout (void);" << be_nl
;
205 *os
<< node
->full_name () << "_slice * _boxed_out (void);" << be_nl
208 // Member variable of underlying type;
209 this->emit_boxed_member_var (node
, "_var");
216 be_visitor_valuebox_ch::visit_enum (be_enum
*node
)
218 return this->emit_for_predef_enum (node
, "", false);
223 be_visitor_valuebox_ch::visit_interface (be_interface
*node
)
225 return this->emit_for_predef_enum (node
, "_ptr", false);
230 be_visitor_valuebox_ch::visit_predefined_type (be_predefined_type
*node
)
232 return this->emit_for_predef_enum (
235 node
->pt () == AST_PredefinedType::PT_any
);
240 be_visitor_valuebox_ch::visit_sequence (be_sequence
*node
)
242 TAO_OutStream
*os
= this->ctx_
->stream ();
244 // Retrieve the node being visited by this be_visitor_valuebox_ch.
245 be_decl
* vb_node
= this->ctx_
->node ();
247 if (node
->anonymous ())
248 { // Our sequence is anonymous so we must generate a declaration
250 be_visitor_context
ctx (*this->ctx_
);
253 // First generate the sequence declaration.
254 be_visitor_sequence_ch
visitor (&ctx
);
256 if (node
->accept (&visitor
) == -1)
258 ACE_ERROR_RETURN ((LM_ERROR
,
259 "(%N:%l) be_visitor_valuebox_ch::"
266 // Retrieve the base type since we will need to do some code
267 // generation for it.
268 be_type
*bt
= dynamic_cast<be_type
*> (node
->base_type ());
272 ACE_ERROR_RETURN ((LM_ERROR
,
273 "(%N:%l) be_visitor_valuebox_ch::"
275 "Bad element type\n"),
279 // Indicate that this type has been used as a sequence element.
280 bt
->seen_in_sequence (true);
282 TAO_INSERT_COMMENT (os
);
284 this->emit_default_constructor();
286 if (node
->unbounded ())
288 // Public constructor with one argument of type ULong
289 *os
<< vb_node
->local_name () << " ( ::CORBA::ULong max);" << be_nl
;
292 // Public constructor for sequence with supplied buffer
293 *os
<< vb_node
->local_name () << " (" << be_idt
<< be_idt
;
295 if (node
->unbounded ())
297 *os
<< be_nl
<< "::CORBA::ULong max,";
300 *os
<< be_nl
<< "::CORBA::ULong length," << be_nl
;
302 // Generate the base type for the buffer.
303 be_visitor_context
ctx (*this->ctx_
);
304 ctx
.state (TAO_CodeGen::TAO_SEQUENCE_BUFFER_TYPE_CH
);
305 be_visitor_sequence_buffer_type
bt_visitor (&ctx
);
306 if (bt
->accept (&bt_visitor
) == -1)
308 ACE_ERROR_RETURN ((LM_ERROR
,
309 " (%N:%l) be_visitor_valuebox_ch::visit_sequence - "
310 "base type visit failed\n"),
314 *os
<< " * buf," << be_nl
315 << "::CORBA::Boolean release = false);" << be_uidt
318 // Public constructor with single argument of type const T&
319 this->emit_constructor_one_arg (node
, "", "const ", "&");
321 // Public copy constructor
322 this->emit_copy_constructor ();
324 *os
<< be_nl
<< "// assignment operator" << be_nl
;
326 // Public assignment operator with one argument of type const T&
327 this->emit_assignment (node
, "", "const ", "&");
329 // Public accessor and modifier methods
330 this->emit_accessor_modifier (node
);
332 // Access to the boxed value for method signatures
333 this->emit_boxed_access (node
, "", "const ", "&", "*");
335 // Generate accessors
337 // Generate base type for sequence then remainder of operator []
338 if (bt
->accept (&bt_visitor
) == -1)
340 ACE_ERROR_RETURN ((LM_ERROR
,
341 " (%N:%l) be_visitor_valuebox_ch::"
343 "base type visit failed\n"),
346 *os
<< "& operator[] ( ::CORBA::ULong index);" << be_nl
;
348 // Generate base type for sequence then remainder of operator []
351 if (bt
->accept (&bt_visitor
) == -1)
353 ACE_ERROR_RETURN ((LM_ERROR
,
354 " (%N:%l) be_visitor_valuebox_ch::"
356 "base type visit failed\n"),
360 *os
<< "& operator[] ( ::CORBA::ULong index) const;" << be_nl_2
361 << "::CORBA::ULong maximum (void) const;" << be_nl
362 << "::CORBA::ULong length (void) const;" << be_nl
363 << "void length ( ::CORBA::ULong len);" << be_nl_2
;
365 // Member variable of underlying type;
366 this->emit_boxed_member_var (node
, "_var");
373 be_visitor_valuebox_ch::visit_string (be_string
*node
)
375 TAO_OutStream
*os
= this->ctx_
->stream ();
377 const char *string_type
;
378 const char *char_type
;
380 if (node
->node_type () == AST_Decl::NT_string
)
382 string_type
= "String";
385 else if (node
->node_type () == AST_Decl::NT_wstring
)
387 string_type
= "WString";
388 char_type
= "::CORBA::WChar";
392 ACE_ERROR ((LM_ERROR
,
393 "(%N:%l) be_visitor_valuebox_ch::visit_string -"
394 "unexpected string node type=%d\n", node
->node_type ()));
398 // Retrieve the node being visited by this be_visitor_valuebox_ch.
399 be_decl
* vb_node
= this->ctx_
->node ();
401 TAO_INSERT_COMMENT (os
);
403 this->emit_default_constructor ();
404 this->emit_constructor_one_arg (node
, "", "", "");
406 // Public constructor with one argument of type const char *
407 this->emit_constructor_one_arg (node
, "", "const ", "");
409 // Public constructor with one argument of type const CORBA::String_var&
410 *os
<< vb_node
->local_name () << " (const ::CORBA::" << string_type
411 << "_var& var);" << be_nl
;
413 // Public copy constructor
414 this->emit_copy_constructor ();
416 *os
<< "// assignment operators" << be_nl
;
418 // Public assignment operator with one argument of type char *
419 this->emit_assignment (node
, "", "", "");
421 // Public assignment operator with one argument of type const char *
422 this->emit_assignment (node
, "", "const ", "");
424 // Public assignment operator with one argument of type
425 // const CORBA::String_var&
426 *os
<< vb_node
->local_name () << "& operator= (const ::CORBA::"
427 << string_type
<< "_var& var);" << be_nl_2
;
429 *os
<< "// Accessor" << be_nl
;
431 // Accessor function takes no arguments and returns a const char *
432 *os
<< "const " << node
->full_name ()
433 << " _value (void) const;" << be_nl_2
;
435 *os
<< "// Modifiers" << be_nl
;
437 // Modifier function with one argument of type char *
438 *os
<< "void _value (" << node
->full_name () << " val);" << be_nl
;
440 // Modifier function with one argument of type const char *
441 *os
<< "void _value (const " << node
->full_name () << " val);"
444 // Modifier function with one argument of type const CORBA::String_var&
445 *os
<< "void _value (const ::CORBA::" << string_type
<< "_var& var);"
448 // Access to the boxed value for method signatures
449 this->emit_boxed_access (node
, "", "const ", "", "");
451 // Overloaded subscript operators
452 *os
<< "// Allows access and modification using a slot." << be_nl
453 << char_type
<< " & operator[] ( ::CORBA::ULong slot);"
455 << "// Allows only accessing thru a slot." << be_nl
456 << char_type
<< " operator[] ( ::CORBA::ULong slot) const;"
459 // Member variable of underlying type;
460 *os
<< be_uidt_nl
<< "private:" << be_idt_nl
461 << "::CORBA::" << string_type
<< "_var" << " _pd_value;" << be_nl
;
468 be_visitor_valuebox_ch::visit_structure (be_structure
*node
)
470 TAO_OutStream
*os
= this->ctx_
->stream ();
472 TAO_INSERT_COMMENT (os
);
474 this->emit_default_constructor();
476 // Public constructor with one argument of const T&
477 this->emit_constructor_one_arg (node
, "", "const ", "&");
479 // Public copy constructor
480 this->emit_copy_constructor ();
482 *os
<< be_nl
<< "// Assignment operator" << be_nl
;
484 // Public assignment operator with one argument of type const T&
485 this->emit_assignment (node
, "", "const ", "&");
487 // Public accessor and modifier methods
488 this->emit_accessor_modifier (node
);
490 // Access to the boxed value for method signatures
491 if (node
->size_type() == AST_Type::FIXED
)
493 this->emit_boxed_access (node
, "", "const ", "&", "");
497 this->emit_boxed_access (node
, "", "const ", "&", "*");
500 // Now generate the accessor and modifier functions for each struct
501 // member. These functions have the same signatures as
502 // acessor and modifier functions for union members.
505 AST_Field
*field
= 0;
507 be_visitor_context
ctx (*this->ctx_
);
509 for (UTL_ScopeActiveIterator
si (node
, UTL_Scope::IK_decls
);
515 if (d
== 0 || (field
= dynamic_cast<AST_Field
*> (d
)) == 0)
517 ACE_ERROR ((LM_ERROR
,
518 "(%N:%l) be_visitor_valuebox_ch::visit_structure -"
519 "bad node in this scope\n"));
523 bt
= dynamic_cast<be_type
*> (field
->field_type ());
525 // Set the node to be visited
526 ctx
.node (dynamic_cast<be_decl
*> (d
));
528 // Create a visitor and use that to process the type.
529 be_visitor_valuebox_field_ch
visitor (&ctx
);
531 if (bt
->accept (&visitor
) == -1)
533 ACE_ERROR ((LM_ERROR
,
534 "(%N:%l) be_visitor_valuebox_ch::visit_structure"
535 " - codegen for struct type failed\n"));
539 TAO_INSERT_COMMENT (os
);
541 // Member variable of underlying type;
542 this->emit_boxed_member_var (node
, "_var");
549 be_visitor_valuebox_ch::visit_typedef (be_typedef
*node
)
551 // Make a decision based on the primitive base type.
552 be_type
*bt
= node
->primitive_base_type ();
554 if (!bt
|| (bt
->accept (this) == -1))
556 ACE_ERROR_RETURN ((LM_ERROR
,
557 " (%N:%l) be_visitor_valuebox_ch::"
559 "Bad primitive type\n"),
568 be_visitor_valuebox_ch::visit_union (be_union
*node
)
570 TAO_OutStream
*os
= this->ctx_
->stream ();
572 TAO_INSERT_COMMENT (os
);
574 this->emit_default_constructor();
576 // Public constructor with single argument of type const T&
577 this->emit_constructor_one_arg (node
, "", "const ", "&");
579 // Public copy constructor
580 this->emit_copy_constructor ();
582 *os
<< be_nl
<< "// Assignment operator" << be_nl
;
584 // Public assignment operator with one argument of type const T&
585 this->emit_assignment (node
, "", "const ", "&");
587 // Public accessor and modifier methods
588 this->emit_accessor_modifier (node
);
590 // Access to the boxed value for method signatures
591 if (node
->size_type() == AST_Type::FIXED
)
593 this->emit_boxed_access (node
, "", "const ", "&", "");
597 this->emit_boxed_access (node
, "", "const ", "&", "*");
600 // Now generate the accessor and modifier functions for each union
604 AST_Field
*field
= 0;
606 be_visitor_context
ctx (*this->ctx_
);
608 for (UTL_ScopeActiveIterator
si (node
, UTL_Scope::IK_decls
);
614 if (d
== 0 || (field
= dynamic_cast<AST_Field
*> (d
)) == 0)
616 ACE_ERROR ((LM_ERROR
,
617 "(%N:%l) be_visitor_valuebox_ch::visit_union -"
618 "bad node in this scope\n"));
622 bt
= dynamic_cast<be_type
*> (field
->field_type ());
624 // Set the node to be visited
625 ctx
.node (dynamic_cast<be_decl
*> (d
));
627 // Create a visitor and use that to process the type.
628 be_visitor_valuebox_field_ch
visitor (&ctx
);
630 if (bt
->accept (&visitor
) == -1)
632 ACE_ERROR ((LM_ERROR
,
633 "(%N:%l) be_visitor_valuebox_ch::visit_union"
634 " - codegen for struct type failed\n"));
638 // Retrieve the disriminant type.
639 bt
= dynamic_cast<be_type
*> (node
->disc_type ());
643 ACE_ERROR_RETURN ((LM_ERROR
,
644 "(%N:%l) be_visitor_valuebox_ch::visit_union - "
645 "bad disciminant type\n"),
649 // The discriminant type may have to be defined here if it was an enum
650 // declaration inside of the union statement.
652 be_visitor_union_discriminant_ch
ud_visitor (&ctx
);
654 if (bt
->accept (&ud_visitor
) == -1)
656 ACE_ERROR_RETURN ((LM_ERROR
,
657 "(%N:%l) be_visitor_union_ch::"
659 "codegen for discriminant failed\n"),
663 TAO_INSERT_COMMENT (os
);
665 // Member variable of underlying type;
666 this->emit_boxed_member_var (node
, "_var");
673 be_visitor_valuebox_ch::emit_for_predef_enum (be_type
*node
,
674 const char * type_suffix
,
677 TAO_OutStream
*os
= this->ctx_
->stream ();
679 TAO_INSERT_COMMENT (os
);
681 this->emit_default_constructor ();
685 this->emit_constructor_one_arg (node
, "", "const ", "&");
688 { // Public constructor with one argument of underlying type
689 this->emit_constructor_one_arg (node
, type_suffix
, "", "");
692 // Public copy constructor
693 this->emit_copy_constructor ();
695 *os
<< be_nl
<< "// Assignment operator" << be_nl
;
698 { // Public assignment operator with one argument of type const T&
699 this->emit_assignment (node
, "", "const ::", "&");
701 this->emit_accessor_modifier (node
);
703 // Access to the boxed value for method signatures
704 this->emit_boxed_access (node
, "", "const ::", "&", "*");
706 // Member variable of underlying type;
707 this->emit_boxed_member_var (node
, "_var");
710 { // Public assignment operator with one argument of underlying type
711 this->emit_assignment (node
, type_suffix
, "", "");
713 // Public accessor and modifier methods
714 *os
<< "// Accessor and modifier" << be_nl
;
716 *os
<< node
->full_name () << type_suffix
717 << " _value (void) const;" << be_nl
;
719 *os
<< "void" << " _value (" << node
->full_name () << type_suffix
720 << " val);" << be_nl_2
;
722 // Access to the boxed value for method signatures
723 this->emit_boxed_access (node
, type_suffix
, "", "", "");
725 // Member variable of underlying type;
726 this->emit_boxed_member_var (node
, type_suffix
);
733 be_visitor_valuebox_ch::emit_default_constructor (void)
735 TAO_OutStream
*os
= this->ctx_
->stream ();
737 // Retrieve the node being visited by this be_visitor_valuebox_ch.
738 be_decl
* vb_node
= this->ctx_
->node ();
740 *os
<< be_nl_2
<< "// Constructors" << be_nl
;
742 // Public default constructor
743 *os
<< vb_node
->local_name () << " (void);" << be_nl
;
747 be_visitor_valuebox_ch::emit_constructor_one_arg (be_decl
*node
,
748 const char * type_suffix
,
749 const char * const_prefix
,
750 const char * ref_modifier
)
752 TAO_OutStream
*os
= this->ctx_
->stream ();
754 // Retrieve the node being visited by this be_visitor_valuebox_ch.
755 be_decl
* vb_node
= this->ctx_
->node ();
757 // Public constructor with one argument of underlying type
758 *os
<< vb_node
->local_name () << " (" << const_prefix
<< node
->full_name ()
759 << type_suffix
<< ref_modifier
<< " val);" << be_nl
;
763 be_visitor_valuebox_ch::emit_copy_constructor (void)
765 TAO_OutStream
*os
= this->ctx_
->stream ();
767 // Retrieve the node being visited by this be_visitor_valuebox_ch.
768 be_decl
* vb_node
= this->ctx_
->node ();
770 // Public Copy constructor
771 *os
<< vb_node
->local_name ()
772 << " (const " << vb_node
->local_name () << "& val);" << be_nl
;
776 be_visitor_valuebox_ch::emit_assignment (be_decl
*node
,
777 const char * type_suffix
,
778 const char * const_prefix
,
779 const char * ref_modifier
)
781 TAO_OutStream
*os
= this->ctx_
->stream ();
783 // Retrieve the node being visited by this be_visitor_valuebox_ch.
784 be_decl
* vb_node
= this->ctx_
->node ();
786 *os
<< vb_node
->local_name () << "& operator= (" << const_prefix
787 << node
->full_name () << type_suffix
<< ref_modifier
<< " val);"
792 be_visitor_valuebox_ch::emit_boxed_access (be_decl
*node
,
793 const char * type_suffix
,
794 const char *const_prefix
,
795 const char *in_ref_modifier
,
796 const char *out_ref_modifier
)
798 TAO_OutStream
*os
= this->ctx_
->stream ();
800 *os
<< "// Access to the boxed value for method signatures" << be_nl
;
802 // Access to the boxed value for method signatures
803 *os
<< const_prefix
<< node
->full_name () << type_suffix
<< in_ref_modifier
804 << " _boxed_in (void) const;" << be_nl
805 << node
->full_name () << type_suffix
<< "&"
806 << " _boxed_inout (void);" << be_nl
807 << node
->full_name () << type_suffix
<< out_ref_modifier
<< "&"
808 << " _boxed_out (void);" << be_nl
;
812 be_visitor_valuebox_ch::emit_accessor_modifier (be_decl
*node
)
814 TAO_OutStream
*os
= this->ctx_
->stream ();
816 *os
<< "// Accessors and modifier" << be_nl
;
818 // Public accessor method (const)
819 *os
<< "const " << node
->full_name () << "& _value (void) const;"
822 // Public accessor method
823 *os
<< node
->full_name () << "& _value (void);" << be_nl
;
825 // Public modifier method
826 *os
<< "void" << " _value (const " << node
->full_name () << "& val);"
832 be_visitor_valuebox_ch::emit_boxed_member_var (be_decl
*node
,
833 const char * type_suffix
)
835 TAO_OutStream
*os
= this->ctx_
->stream ();
837 // Member variable of underlying type;
838 *os
<< be_uidt_nl
<< "private:" << be_idt_nl
839 << node
->full_name () << type_suffix
<< " _pd_value;" << be_nl
;