summaryrefslogtreecommitdiff
path: root/trunk/TAO/TAO_IDL/be/be_union_branch.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/TAO/TAO_IDL/be/be_union_branch.cpp')
-rw-r--r--trunk/TAO/TAO_IDL/be/be_union_branch.cpp200
1 files changed, 200 insertions, 0 deletions
diff --git a/trunk/TAO/TAO_IDL/be/be_union_branch.cpp b/trunk/TAO/TAO_IDL/be/be_union_branch.cpp
new file mode 100644
index 00000000000..22cd43f8a86
--- /dev/null
+++ b/trunk/TAO/TAO_IDL/be/be_union_branch.cpp
@@ -0,0 +1,200 @@
+// $Id$
+
+// ============================================================================
+//
+// = LIBRARY
+// TAO IDL
+//
+// = FILENAME
+// be_union_branch.cpp
+//
+// = DESCRIPTION
+// Extension of class AST_UnionBranch that provides additional means for C++
+// mapping.
+//
+// = AUTHOR
+// Copyright 1994-1995 by Sun Microsystems, Inc.
+// and
+// Aniruddha Gokhale
+//
+// ============================================================================
+
+#include "be_union_branch.h"
+#include "be_union.h"
+#include "be_type.h"
+#include "be_enum.h"
+#include "be_visitor.h"
+#include "be_helper.h"
+#include "ast_union_label.h"
+#include "ace/Log_Msg.h"
+
+ACE_RCSID (be,
+ be_union_branch,
+ "$Id$")
+
+be_union_branch::be_union_branch (void)
+ : COMMON_Base (),
+ AST_Decl (),
+ AST_Field (),
+ AST_UnionBranch (),
+ be_decl ()
+{
+}
+
+be_union_branch::be_union_branch (UTL_LabelList *ll,
+ AST_Type *ft,
+ UTL_ScopedName *n)
+ : COMMON_Base (ft->is_local (),
+ ft->is_abstract ()),
+ AST_Decl (AST_Decl::NT_union_branch,
+ n),
+ AST_Field (AST_Decl::NT_union_branch,
+ ft,
+ n),
+ AST_UnionBranch (ll,
+ ft,
+ n),
+ be_decl (AST_Decl::NT_union_branch,
+ n)
+{
+}
+
+int
+be_union_branch::gen_label_value (TAO_OutStream *os, unsigned long index)
+{
+ AST_Expression *e = this->label (index)->label_val ();
+
+ if (e->ec () != AST_Expression::EC_symbol)
+ {
+ // Easy, just a number...
+ *os << e;
+ return 0;
+ }
+
+ // If the enum is not in the global scope we have to prefix it.
+ be_union *u =
+ be_union::narrow_from_scope (this->defined_in ());
+
+ if (u == 0)
+ {
+ return -1;
+ }
+
+ be_type* dt =
+ be_type::narrow_from_decl (u->disc_type ());
+
+ if (dt == 0)
+ {
+ return -1;
+ }
+
+ // Check if discriminator is a typedef of an integer. If so, and the
+ // first IF block in this function didn't catch it, then we
+ // are a constant of this type. We can't generate the constant's name,
+ // we must generate the underlying integer value for the
+ // label value.
+ if (dt->node_type () == AST_Decl::NT_pre_defined)
+ {
+ *os << e;
+ return 0;
+ }
+
+ // Find where was the enum defined, if it was defined in the globa
+ // scope, then it is easy to generate the enum values....
+ be_scope* scope =
+ be_scope::narrow_from_scope (dt->defined_in ());
+
+ if (scope == 0)
+ {
+ *os << e->n ();
+ return 0;
+ }
+
+ // But if it was generated inside a module or something similar then
+ // we must prefix the enum value with something...
+ be_decl* decl = scope->decl ();
+
+ *os << decl->full_name () << "::" << e->n ()->last_component ();
+
+ return 0;
+}
+
+int
+be_union_branch::gen_default_label_value (TAO_OutStream *os,
+ be_union *bu)
+{
+ be_union::DefaultValue dv;
+
+ if (bu->default_value (dv) == -1)
+ {
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_visitor_union_branch::"
+ "gen_default_label_value - "
+ "computing default value failed\n"),
+ -1);
+ }
+
+ switch (bu->udisc_type ())
+ {
+ case AST_Expression::EV_short:
+ *os << dv.u.short_val;
+ break;
+ case AST_Expression::EV_ushort:
+ *os << dv.u.ushort_val;
+ break;
+ case AST_Expression::EV_long:
+ *os << dv.u.long_val;
+ break;
+ case AST_Expression::EV_ulong:
+ *os << dv.u.ulong_val;
+ break;
+ case AST_Expression::EV_char:
+ os->print ("%d", dv.u.char_val);
+ break;
+ case AST_Expression::EV_bool:
+ *os << (dv.u.bool_val == 0 ? "false" : "true");
+ break;
+ case AST_Expression::EV_enum:
+ // The discriminant is an enum. Some compilers will
+ // not accept a numeric value assigned to this
+ // discriminant, so we must generate the string name.
+ {
+ AST_ConcreteType *act = bu->disc_type ();
+ be_enum *be = be_enum::narrow_from_decl (act);
+
+ // The function value_to_name() takes care of adding
+ // any necessary scoping to the output.
+ *os << be->value_to_name (dv.u.enum_val);
+ break;
+ }
+ case AST_Expression::EV_longlong:
+ case AST_Expression::EV_ulonglong:
+ // Unimplemented.
+ default:
+ // Error caught earlier.
+ ACE_ERROR_RETURN ((LM_ERROR,
+ "(%N:%l) be_visitor_union_branch::"
+ "gen_default_label_value - "
+ "bad or unimplemented discriminant type\n"),
+ -1);
+ }
+
+ return 0;
+}
+
+int
+be_union_branch::accept (be_visitor *visitor)
+{
+ return visitor->visit_union_branch (this);
+}
+
+void
+be_union_branch::destroy (void)
+{
+ this->be_decl::destroy ();
+ this->AST_UnionBranch::destroy ();
+}
+
+// Narrowing.
+IMPL_NARROW_METHODS2 (be_union_branch, AST_UnionBranch, be_decl)
+IMPL_NARROW_FROM_DECL (be_union_branch)