summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkolpackov <kolpackov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2002-01-18 18:42:59 +0000
committerkolpackov <kolpackov@ae88bc3d-4319-0410-8dbf-d08b4c9d3795>2002-01-18 18:42:59 +0000
commite307e7b16508ad5cb86029933dfcb9ee7a74f6ca (patch)
treee8156f6135dc7b979189fc681da1654075afefac
parent510d6f134782eb006891149e21558cee2f2c59b2 (diff)
downloadATCD-e307e7b16508ad5cb86029933dfcb9ee7a74f6ca.tar.gz
*** empty log message ***
-rw-r--r--TAO/TAO_IDL/be/be_visitor_typecode/typecode_decl.cpp6
-rw-r--r--TAO/TAO_IDL/be/be_visitor_typecode/typecode_defn.cpp475
-rw-r--r--TAO/TAO_IDL/be_include/be_valuetype.h21
-rw-r--r--TAO/TAO_IDL/be_include/be_visitor_valuetype.h2
-rw-r--r--TAO/TAO_IDL/be_include/be_visitor_valuetype/any_op_ch.h2
-rw-r--r--TAO/TAO_IDL/be_include/be_visitor_valuetype/any_op_cs.h2
6 files changed, 489 insertions, 19 deletions
diff --git a/TAO/TAO_IDL/be/be_visitor_typecode/typecode_decl.cpp b/TAO/TAO_IDL/be/be_visitor_typecode/typecode_decl.cpp
index 85879c2b5e1..aac1ea44444 100644
--- a/TAO/TAO_IDL/be/be_visitor_typecode/typecode_decl.cpp
+++ b/TAO/TAO_IDL/be/be_visitor_typecode/typecode_decl.cpp
@@ -123,3 +123,9 @@ be_visitor_typecode_decl::visit_union (be_union *node)
{
return this->visit_type (node);
}
+
+int
+be_visitor_typecode_decl::visit_valuetype (be_valuetype *node)
+{
+ return this->visit_type (node);
+}
diff --git a/TAO/TAO_IDL/be/be_visitor_typecode/typecode_defn.cpp b/TAO/TAO_IDL/be/be_visitor_typecode/typecode_defn.cpp
index edf7b3c767b..0cab7ed5b14 100644
--- a/TAO/TAO_IDL/be/be_visitor_typecode/typecode_defn.cpp
+++ b/TAO/TAO_IDL/be/be_visitor_typecode/typecode_defn.cpp
@@ -112,6 +112,93 @@ be_visitor_typecode_defn::visit_members (AST_Structure *node)
return 0;
}
+int
+be_visitor_typecode_defn::visit_members (be_valuetype *node)
+{
+ // proceed if the number of members in our scope is greater than 0
+ if (node->nmembers () > 0)
+ {
+ // initialize an iterator to iterate thru our scope
+ UTL_ScopeActiveIterator *si;
+ ACE_NEW_RETURN (si,
+ UTL_ScopeActiveIterator (node,
+ UTL_Scope::IK_decls),
+ -1);
+
+ this->elem_number_ = 0;
+
+ // continue until each element is visited
+ for (;!si->is_done ();si->next())
+ {
+ AST_Decl *d = si->item ();
+
+ if (!d)
+ {
+ delete si;
+ ACE_ERROR_RETURN ((
+ LM_ERROR,
+ "(%N:%l) be_visitor_typecode_defn::visit_members - "
+ "bad node in this scope\n"), -1);
+ }
+
+ AST_Field *field = AST_Field::narrow_from_decl (d);
+
+ if (!field)
+ {
+ continue;
+ }
+
+ be_decl *bd = be_decl::narrow_from_decl (d);
+ // set the scope node as "node" in which the code is being
+ // generated so that elements in the node's scope can use it
+ // for code generation
+
+ this->ctx_->scope (node->decl ());
+
+ // set the node to be visited
+ this->ctx_->node (bd);
+ this->elem_number_++;
+
+ // Do any pre processing using the next item info.
+ if (this->pre_process (bd) == -1)
+ {
+ ACE_ERROR_RETURN ((
+ LM_ERROR,
+ "(%N:%l) be_visitor_typecode_defn::visit_members - "
+ "pre processing failed\n"
+ ), -1);
+ }
+
+ // Send the visitor.
+ if (bd == 0 || bd->accept (this) == -1)
+ {
+ ACE_ERROR_RETURN ((
+ LM_ERROR,
+ "(%N:%l) be_visitor_typecode_defn::visit_members - "
+ "codegen for scope failed\n"
+ ), -1);
+
+ }
+
+ // Do any post processing using this item info.
+ if (this->post_process (bd) == -1)
+ {
+ ACE_ERROR_RETURN ((
+ LM_ERROR,
+ "(%N:%l) be_visitor_typecode_defn::visit_members - "
+ "post processing failed\n"
+ ), -1);
+ }
+
+ } // end of for loop
+
+ delete si;
+ }
+
+ return 0;
+}
+
+
// the following needs to be done to deal with the most bizarre behavior of
// MSVC++ compiler
int
@@ -234,8 +321,19 @@ be_visitor_typecode_defn::visit_type (be_type *node)
*os << "CORBA::tk_except";
break;
case AST_Decl::NT_interface:
- *os << "CORBA::tk_objref";
- break;
+ {
+ // Yet another fruit of interface being a valuetype sometimes :-(
+ AST_Interface* iface = AST_Interface::narrow_from_decl (node);
+ if (iface != 0 && iface->is_valuetype ())
+ {
+ *os << "CORBA::tk_value";
+ }
+ else
+ {
+ *os << "CORBA::tk_objref";
+ }
+ break;
+ }
case AST_Decl::NT_sequence:
*os << "CORBA::tk_sequence";
break;
@@ -693,6 +791,39 @@ be_visitor_typecode_defn::visit_union (be_union *node)
-1);
}
+int
+be_visitor_typecode_defn::visit_valuetype (be_valuetype *node)
+{
+ switch (this->ctx_->sub_state ())
+ {
+ case TAO_CodeGen::TAO_TC_DEFN_TYPECODE:
+ return this->visit_type (node);
+ case TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED:
+ return this->gen_typecode (node);
+
+ case TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION:
+ return this->gen_encapsulation (node);
+
+ case TAO_CodeGen::TAO_TC_DEFN_TC_SIZE:
+ this->computed_tc_size_ = this->compute_tc_size (node);
+ return ((this->computed_tc_size_ > 0) ? 0 : -1);
+ case TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN:
+ this->computed_encap_len_ = this->compute_encap_length (node);
+ return ((this->computed_encap_len_ > 0) ? 0 : -1);
+ case TAO_CodeGen::TAO_TC_DEFN_SCOPE:
+ case TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN:
+ return this->visit_members (node);
+ default:
+ // error
+ break;
+ }
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%N:%l) be_visitor_typecode_defn::")
+ ACE_TEXT ("visit - bad sub state ")
+ ACE_TEXT ("in visitor context\n")),
+ -1);
+}
+
int
be_visitor_typecode_defn::visit_union_branch (be_union_branch *node)
{
@@ -1124,6 +1255,23 @@ be_visitor_typecode_defn::gen_encapsulation (be_field *node)
// subsequent fields for which we have to be in the "gen scope"
// substate
this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE);
+
+ if (node->visibility() != AST_Field::vis_NA)
+ {
+ // generate visibility marker
+
+ // Even though visibility marker is UShort it seems that
+ // it would always be aligned on ULong boundary.
+ ACE_CDR::ULong visibility =
+ node->visibility() == AST_Field::vis_PRIVATE ? 0 : 1;
+
+ os->indent (); // start from current indentation level
+ *os << visibility << ", // data memeber visibility marker"
+ << "\n\n";
+
+ this->tc_offset_ += sizeof (ACE_CDR::ULong);
+ }
+
return 0;
}
@@ -2084,6 +2232,178 @@ be_visitor_typecode_defn::gen_encapsulation (be_union_branch *node)
return 0;
}
+int
+be_visitor_typecode_defn::gen_typecode (be_valuetype *node)
+{
+ TAO_OutStream *os = this->ctx_->stream (); // output stream
+
+ os->indent (); // start from whatever indentation level we were at
+
+ // check if we are repeated
+ const be_visitor_typecode_defn::QNode *qnode =
+ this->queue_lookup (this->tc_queue_, node);
+ if (qnode)
+ {
+ // we are repeated, so we must generate an indirection here
+ *os << "0xffffffff, // indirection" << be_nl;
+ this->tc_offset_ += sizeof (ACE_CDR::ULong);
+ // the offset must point to the tc_kind value of the first occurrence of
+ // this type
+ os->print ("0x%x, // negative offset (%ld)\n",
+ (qnode->offset - this->tc_offset_),
+ (qnode->offset - this->tc_offset_));
+ this->tc_offset_ += sizeof (ACE_CDR::ULong);
+ }
+ else
+ {
+ if (be_global->opt_tc () ||
+ node->in_recursion ())
+ {
+ if (this->queue_insert (this->tc_queue_,
+ node,
+ this->tc_offset_) == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_visitor_typecode_defn::"
+ "visit_type - "
+ "queue insert failed\n"),
+ -1);
+ }
+ }
+
+ *os << "CORBA::tk_value, // typecode kind" << be_nl;
+ // size of the enum
+ this->tc_offset_ += sizeof (ACE_CDR::ULong);
+
+ // reset the compute queue to set the stage for computing our
+ // encapsulation length
+ this->queue_reset (this->compute_queue_);
+
+ // emit the encapsulation length
+ this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN);
+ if (node->accept (this) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%N:%l) - be_visitor_typecode_defn")
+ ACE_TEXT ("gen_typecode (valuetype) - ")
+ ACE_TEXT ("Failed to get encap length\n")),
+ -1);
+ }
+ // reset the compute queue since we must not affect computation of other
+ // nodes
+ this->queue_reset (this->compute_queue_);
+
+ *os << this->computed_encap_len_ << ", // encapsulation length"
+ << be_idt << "\n";
+ // size of the encap length
+ this->tc_offset_ += sizeof (ACE_CDR::ULong);
+
+ // now emit the encapsulation
+ this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAPSULATION);
+ if (node->accept (this) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%N:%l) be_visitor_typecode_defn")
+ ACE_TEXT ("::gen_typecode (valuetype) - ")
+ ACE_TEXT ("failed to generate encapsulation\n")),
+ -1);
+ }
+ *os << be_uidt << "\n";
+ }
+ return 0;
+}
+
+int
+be_visitor_typecode_defn::gen_encapsulation (be_valuetype *node)
+{
+ TAO_OutStream *os = this->ctx_->stream (); // output stream
+
+ os->indent (); // start from whatever indentation level we were at
+
+ *os << "TAO_ENCAP_BYTE_ORDER, // byte order" << be_nl;
+ // size of the encapsulation byte order flag. Although it is 1 byte, the
+ // aligned size is 4 bytes
+ this->tc_offset_ += sizeof (ACE_CDR::ULong);
+
+ // STEP 1: generate repoID
+ this->gen_repoID (node);
+
+ // STEP 2: generate name
+ os->indent ();
+ this->gen_name (node);
+
+ // STEP 3: generate ValueModifier
+
+ // By spec ValueModifier is UShort but aligned size
+ // seems always to be 4.
+ os->indent ();
+
+ // TAO doesn't support neither CUSTOM nor TRUNCATABLE
+ // valuetypes. So basically need to choose between
+ // VM_NONE = 0 and VM_ABSTRACT = 2
+ ACE_CDR::ULong value_modifier = node->is_abstract_valuetype () ? 2 : 0;
+
+ *os << value_modifier << ", // value modifier" << "\n";
+
+ this->tc_offset_ += sizeof (ACE_CDR::ULong);
+
+ //STEP 4: generate TypeCode of concrete base
+
+ AST_Interface *inherited = 0;
+ if (node->n_inherits () > 0 &&
+ ( // Statefull base valuetype is always first
+ inherited =
+ AST_Interface::narrow_from_decl(node->inherits ()[0])
+ ) != 0 &&
+ inherited->is_valuetype () &&
+ !inherited->is_abstract ()
+ )
+ {
+ // Got non-abstract base valuetype. Now emit its typecode
+ be_valuetype *vt = be_valuetype::narrow_from_decl(node->inherits ()[0]);
+ this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_TYPECODE_NESTED);
+ if (!vt || vt->accept (this) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%N:%l) be_visitor_typecode_defn")
+ ACE_TEXT ("::gen_encapsulation (valuetype) - ")
+ ACE_TEXT ("failed to generate typecode\n")),
+ -1);
+ }
+ // revert the state to what it was before
+ this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE);
+ }
+ else
+ {
+ // emit tk_null
+ os->indent ();
+ *os << "CORBA::tk_null, // no stateful base valuetype"
+ << "\n\n";
+
+ // size of the enum
+ this->tc_offset_ += sizeof (ACE_CDR::ULong);
+ }
+
+ //STEP 5: generate the member count
+ os->indent ();
+
+ *os << node->data_members_count () << ", // member count\n";
+ // size of the member count
+ this->tc_offset_ += sizeof (ACE_CDR::ULong);
+
+ //STEP 6: hand over to the scope to generate the typecode for elements
+ this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE);
+
+ if (node->accept (this) == -1)
+ {
+ ACE_ERROR_RETURN((
+ LM_ERROR,
+ "be_valuetype: cannot generate typecode for members\n"), -1);
+ }
+
+ return 0;
+}
+
// = methods for computing typecode and encapsulation sizes
@@ -2376,6 +2696,16 @@ be_visitor_typecode_defn::compute_encap_length (be_field *node)
// revert the sub state
this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN);
+ if (node->visibility() != AST_Field::vis_NA)
+ {
+ // count visibility marker
+
+ // Even though visibility marker is UShort it seems that
+ // it would always be aligned on ULong boundary.
+ this->computed_encap_len_ += 4;
+ }
+
+
return this->computed_encap_len_;
}
@@ -2912,6 +3242,147 @@ be_visitor_typecode_defn::compute_encap_length (be_union_branch *node)
return this->computed_encap_len_;
}
+ACE_CDR::Long
+be_visitor_typecode_defn::compute_tc_size (be_valuetype *node)
+{
+ // while computing the encapsulation length we must keep in mind the typecode
+ // that has gotten generated until this point. Hence, we must first check the
+ // "tc_queue" to ensure if are already there somewhere in a previous
+ // encapsulation in which case we must count only the bytes for the
+ // indirection. If we are not already generated, we must then check if we
+ // have already been counted in the current computation or not by checking
+ // for our presence in the compute queue. In both cases, we only include the
+ // 8 bytes in the computation
+ if (this->queue_lookup (this->tc_queue_, node) ||
+ this->queue_lookup (this->compute_queue_, node))
+ {
+ this->computed_tc_size_ = 4 + 4;
+ }
+ else
+ {
+ if (be_global->opt_tc () ||
+ node->in_recursion ())
+ {
+ if (this->queue_insert (this->compute_queue_,
+ node,
+ this->tc_offset_) == 0)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_visitor_typecode_defn::"
+ "compute_tc_size (valuetype) - "
+ "queue insert failed\n"),
+ -1);
+ }
+ }
+
+ this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN);
+ if (node->accept (this) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%N:%l) be_visitor_typecode_defn")
+ ACE_TEXT ("::compute_tc_size (valuetype) - ")
+ ACE_TEXT ("cannot compute encap len\n")),
+ -1);
+ }
+
+ this->computed_tc_size_ = 4 + 4 + this->computed_encap_len_;
+ }
+ return this->computed_tc_size_;
+}
+
+ACE_CDR::Long
+be_visitor_typecode_defn::compute_encap_length (be_valuetype *node)
+{
+ // STEP 1:
+ ACE_CDR::Long encap_len = 4; // holds the byte order flag
+
+ // STEP 2:
+ encap_len += this->repoID_encap_len (node); // repoID
+
+ //STEP 3: do the same thing for the local name
+ encap_len += this->name_encap_len (node);
+
+ // STEP 4:
+ encap_len += 4; // to hold the ValueModifier
+
+
+ // STEP 5: get encapsulation length for concrete base valuetype
+ AST_Interface *inherited = 0;
+ if (node->n_inherits () > 0 &&
+ ( // Statefull abse valuetype is always first
+ inherited =
+ AST_Interface::narrow_from_decl(node->inherits ()[0])
+ ) != 0 &&
+ inherited->is_valuetype () &&
+ !inherited->is_abstract ()
+ )
+ {
+ // Got non-abstract base valuetype.
+
+ this->computed_encap_len_ = 0;
+
+ be_valuetype *vt = be_valuetype::narrow_from_decl(node->inherits ()[0]);
+ this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_TC_SIZE);
+ if (!vt || vt->accept (this) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%N:%l) be_visitor_typecode_defn")
+ ACE_TEXT ("::compute_encap_len (valuetype) - ")
+ ACE_TEXT ("failed to compute len\n")),
+ -1);
+ }
+ // revert the state to what it was before
+ this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_ENCAP_LEN);
+
+ encap_len += this->computed_encap_len_;
+ }
+ else
+ {
+ encap_len += 4; // to hold the CORBA::tk_null
+ }
+
+ //STEP 6:
+ encap_len += 4; // to hold the member count
+
+ // save the current value of scope len and start with a fresh one for our
+ // scope length computation
+ if (this->push (this->computed_scope_encap_len_) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%N:%l) be_visitor_typecode_defn")
+ ACE_TEXT ("::compute_encap_len (struct) - ")
+ ACE_TEXT ("push failed\n")),
+ -1);
+ }
+ this->computed_scope_encap_len_ = 0;
+
+ // compute encap length for members
+ this->ctx_->sub_state (TAO_CodeGen::TAO_TC_DEFN_SCOPE_LEN);
+ if (node->accept (this) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%N:%l) be_visitor_typecode_defn")
+ ACE_TEXT ("::compute_encap_len (valuetype) - ")
+ ACE_TEXT ("cannot compute scope tc size\n")),
+ -1);
+ }
+
+ this->computed_encap_len_ = encap_len + this->computed_scope_encap_len_;
+
+ // pop off the previous value of computed_scope_len_
+ if (this->pop (this->computed_scope_encap_len_) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ ACE_TEXT ("(%N:%l) be_visitor_typecode_defn")
+ ACE_TEXT ("::compute_encap_len (valuetype) - ")
+ ACE_TEXT ("pop failed\n")),
+ -1);
+ }
+
+ return this->computed_encap_len_;
+}
+
+
// helpers that accomplish a common task - that of generating the repository
// IDs and names in a TypeCode description
diff --git a/TAO/TAO_IDL/be_include/be_valuetype.h b/TAO/TAO_IDL/be_include/be_valuetype.h
index cb01a210ee2..7e16a9c89e4 100644
--- a/TAO/TAO_IDL/be_include/be_valuetype.h
+++ b/TAO/TAO_IDL/be_include/be_valuetype.h
@@ -80,21 +80,6 @@ public:
const char *full_obv_skel_name (void);
// Retrieve the fully scoped skel class name.
- // TODO.
-#if 0
- virtual int gen_typecode (void);
- // Generate the typecode.
-
- virtual int gen_encapsulation (void);
- // Encapsulation for parameters.
-
- virtual long tc_size (void);
- // Return typecode size.
-
- virtual long tc_encap_len (void);
- // Return length of encapsulation.
-#endif
-
const char *field_pd_prefix (void);
const char *field_pd_postfix (void);
@@ -114,6 +99,12 @@ public:
void compute_fullobvskelname (void);
// Compute the fully scoped skel class name.
+ ACE_CDR::ULong data_members_count (
+ AST_Field::Visibility vis = AST_Field::vis_NA);
+ // Compute the count of private/public/all data members.
+
+ virtual idl_bool in_recursion (AST_Type *node = 0);
+ // Check if we are in recursion.
private:
char *full_obv_skel_name_;
diff --git a/TAO/TAO_IDL/be_include/be_visitor_valuetype.h b/TAO/TAO_IDL/be_include/be_visitor_valuetype.h
index 873ab40c764..caae15f0c57 100644
--- a/TAO/TAO_IDL/be_include/be_visitor_valuetype.h
+++ b/TAO/TAO_IDL/be_include/be_visitor_valuetype.h
@@ -48,5 +48,7 @@
#include "be_visitor_valuetype/valuetype_init_ci.h"
#include "be_visitor_valuetype/valuetype_init_cs.h"
#include "be_visitor_valuetype/valuetype_init_arglist_ch.h"
+#include "be_visitor_valuetype/any_op_ch.h"
+#include "be_visitor_valuetype/any_op_cs.h"
#endif /* TAO_BE_VISITOR_VALUETYPE_H */
diff --git a/TAO/TAO_IDL/be_include/be_visitor_valuetype/any_op_ch.h b/TAO/TAO_IDL/be_include/be_visitor_valuetype/any_op_ch.h
index 2c5846ae5a9..afb3290262d 100644
--- a/TAO/TAO_IDL/be_include/be_visitor_valuetype/any_op_ch.h
+++ b/TAO/TAO_IDL/be_include/be_visitor_valuetype/any_op_ch.h
@@ -41,7 +41,7 @@ public:
// destructor
virtual int visit_valuetype (be_valuetype *node);
- // visit interface
+ // visit valuetype
};
#endif /* _BE_VALUETYPE_ANY_OP_CH_H_ */
diff --git a/TAO/TAO_IDL/be_include/be_visitor_valuetype/any_op_cs.h b/TAO/TAO_IDL/be_include/be_visitor_valuetype/any_op_cs.h
index db466d4a945..3c930612a46 100644
--- a/TAO/TAO_IDL/be_include/be_visitor_valuetype/any_op_cs.h
+++ b/TAO/TAO_IDL/be_include/be_visitor_valuetype/any_op_cs.h
@@ -41,7 +41,7 @@ public:
// destructor
virtual int visit_valuetype (be_valuetype *node);
- // visit interface
+ // visit valuetype
};
#endif /* _BE_VALUETYPE_ANY_OP_CS_H_ */