📄 ifr_adding_visitor_union.cpp
字号:
/* -*- c++ -*- */
// ifr_adding_visitor_union.cpp,v 1.17 2003/10/28 18:34:03 bala Exp
#include "ast_enum.h"
#include "ast_expression.h"
#include "ast_union.h"
#include "ast_union_branch.h"
#include "ast_union_label.h"
#include "utl_identifier.h"
#include "ifr_adding_visitor_union.h"
#include "ifr_adding_visitor_structure.h"
#include "tao/Any_Unknown_IDL_Type.h"
ACE_RCSID (IFR_Service,
ifr_adding_visitor_union,
"ifr_adding_visitor_union.cpp,v 1.17 2003/10/28 18:34:03 bala Exp")
ifr_adding_visitor_union::ifr_adding_visitor_union (
AST_Decl *scope,
CORBA::Boolean is_nested
)
: ifr_adding_visitor (scope),
is_nested_ (is_nested)
{
}
ifr_adding_visitor_union::~ifr_adding_visitor_union (void)
{
}
// Specialized visit_scope method for unions only.
int
ifr_adding_visitor_union::visit_scope (UTL_Scope *node)
{
// If the union has members that are scopes but not unions,
// the regular visit_scope method should be called instead.
if (node->scope_node_type () != AST_Decl::NT_union)
{
return ifr_adding_visitor::visit_scope (node);
}
AST_Union *u = AST_Union::narrow_from_scope (node);
CORBA::ULong nfields = ACE_static_cast (CORBA::ULong,
u->nfields ());
this->members_.length (nfields);
AST_Field **f = 0;
// Index into members_.
CORBA::ULong index = 0;
ACE_DECLARE_NEW_CORBA_ENV;
ACE_TRY
{
// Visit each field.
for (CORBA::ULong i = 0; i < nfields; ++i)
{
if (u->field (f, i) != 0)
{
ACE_ERROR_RETURN ((
LM_ERROR,
ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
ACE_TEXT ("visit_scope -")
ACE_TEXT (" field node access failed\n")
),
-1
);
}
AST_Type *ft = (*f)->field_type ();
idl_bool defined_here = ft->is_child (this->scope_);
// If the union member is defined in the union, we have to
// do some visiting - otherwise we can just look up the entry.
if (defined_here)
{
if (ft->node_type () == AST_Decl::NT_union)
{
// Since the enclosing scope hasn't been created yet,
// we make a special visitor to create this member
// at global scope and move it into the union later.
ifr_adding_visitor_union visitor (ft,
1);
if (ft->ast_accept (&visitor) == -1)
{
ACE_ERROR_RETURN ((
LM_ERROR,
ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
ACE_TEXT ("visit_scope -")
ACE_TEXT (" failed to accept visitor\n")
),
-1
);
}
this->ir_current_ =
CORBA::IDLType::_duplicate (visitor.ir_current ());
CORBA::Contained_ptr tmp =
CORBA::Contained::_narrow (visitor.ir_current ()
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
this->move_queue_.enqueue_tail (tmp);
}
else
{
if (ft->ast_accept (this) == -1)
{
ACE_ERROR_RETURN ((
LM_ERROR,
ACE_TEXT ("(%N:%l) ifr_adding_visitor_union::")
ACE_TEXT ("visit_scope -")
ACE_TEXT (" failed to accept visitor\n")
),
-1
);
}
}
}
else
{
// Updates ir_current_.
this->get_referenced_type (ft
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
}
// Get the case label(s).
AST_UnionBranch *ub = 0;
AST_UnionLabel *case_label = 0;
ub = AST_UnionBranch::narrow_from_decl (*f);
unsigned long len = ub->label_list_length ();
// If there are multiple case labels, we will have an element
// in the UnionMemberSeq for each label, not just for each member,
// so the list length and the loop terminator must both be
// increased accordingly.
if (len > 1)
{
this->members_.length (this->members_.length () + len - 1);
}
for (unsigned long j = 0; j < len; ++j)
{
case_label = ub->label (j);
// Is this a regular label or default label?
if (case_label->label_kind () == AST_UnionLabel::UL_label)
{
AST_Expression::AST_ExprValue *ev =
case_label->label_val ()->ev ();
// If the discriminator is an enum, we can't just insert
// a ulong into the Any member of struct UnionMember.
if (u->disc_type ()->node_type () == AST_Decl::NT_enum)
{
TAO_OutputCDR cdr;
cdr.write_ulong (ev->u.ulval);
TAO::Unknown_IDL_Type *unk = 0;
ACE_NEW_RETURN (unk,
TAO::Unknown_IDL_Type (
this->disc_tc_.in (),
cdr.begin (),
TAO_ENCAP_BYTE_ORDER
),
-1);
this->members_[index].label.replace (unk);
}
else
{
this->load_any (ev,
this->members_[index].label);
}
}
else // Default case label.
{
this->members_[index].label <<= CORBA::Any::from_octet (0);
}
this->members_[index].name =
CORBA::string_dup ((*f)->local_name ()->get_string ());
// IfR method create_union does not use this - it just needs
// to be non-zero for marshaling.
this->members_[index].type =
CORBA::TypeCode::_duplicate (CORBA::_tc_void);
this->members_[index++].type_def =
CORBA::IDLType::_duplicate (this->ir_current_.in ());
}
}
}
ACE_CATCHANY
{
ACE_PRINT_EXCEPTION (
ACE_ANY_EXCEPTION,
ACE_TEXT ("ifr_adding_visitor_union::visit_scope")
);
return -1;
}
ACE_ENDTRY;
return 0;
}
int
ifr_adding_visitor_union::visit_structure (AST_Structure *node)
{
ACE_DECLARE_NEW_CORBA_ENV;
ACE_TRY
{
// Is this struct already in the respository?
CORBA::Contained_var prev_def =
be_global->repository ()->lookup_id (node->repoID ()
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
// If not, create a new entry.
if (CORBA::is_nil (prev_def.in ()))
{
ifr_adding_visitor_structure visitor (node,
1);
int retval = visitor.visit_structure (node);
if (retval == 0)
{
// Get the result of the visit.
this->ir_current_ =
CORBA::IDLType::_duplicate (visitor.ir_current ());
CORBA::Contained_ptr tmp =
CORBA::Contained::_narrow (visitor.ir_current ()
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
// Since the enclosing UnionDef hasn't been created
// yet, we don't have a scope, so this nested StructDef
// (which was created at global scope) goes on the
// queue to be moved later.
this->move_queue_.enqueue_tail (tmp);
}
return retval;
}
else
{
// If the line below is true, we are clobbering a previous
// entry (from another IDL file) of another type. In that
// case we do what other ORB vendors do, and destroy the
// original entry, create the new one, and let the user beware.
if (node->ifr_added () == 0)
{
prev_def->destroy (ACE_ENV_SINGLE_ARG_PARAMETER);
ACE_TRY_CHECK;
// This call will take the other branch.
return this->visit_structure (node);
}
this->ir_current_ =
CORBA::IDLType::_narrow (prev_def.in ()
ACE_ENV_ARG_PARAMETER);
ACE_TRY_CHECK;
}
}
ACE_CATCHANY
{
ACE_PRINT_EXCEPTION (
ACE_ANY_EXCEPTION,
ACE_TEXT ("ifr_adding_visitor_union::visit_structure")
);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -