ast_union.cpp
来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 1,256 行 · 第 1/3 页
CPP
1,256 行
d = e->lookup_by_name (sn,
I_TRUE);
if (d == 0 || d->defined_in () != e)
{
idl_global->err ()->enum_val_lookup_failure (this,
e,
sn);
return b;
}
// OK, now see if this symbol is already used as the label of
// some other branch.
for (UTL_ScopeActiveIterator i (this, UTL_Scope::IK_decls);
!i.is_done();
i.next ())
{
d = i.item ();
if (d->node_type () == AST_Decl::NT_union_branch)
{
fb = AST_UnionBranch::narrow_from_decl (d);
if (fb == 0)
{
continue;
}
if (fb->label() != 0
&& fb->label ()->label_kind () == AST_UnionLabel::UL_label
&& fb->label ()->label_val ()->compare (lv))
{
idl_global->err ()->error2 (UTL_Error::EIDL_MULTIPLE_BRANCH,
this,
b);
return b;
}
}
}
return 0;
}
// Look up a branch by value. This is the top level branch label resolution
// entry point. It dispatches to the right lookup function depending on the
// union discriminator type.
AST_UnionBranch *
AST_Union::lookup_branch (AST_UnionBranch *branch)
{
AST_UnionLabel *label = 0;
if (branch != 0)
{
label = branch->label ();
}
if (label != 0)
{
if (label->label_kind () == AST_UnionLabel::UL_default)
{
return this->lookup_default ();
}
if (this->pd_udisc_type == AST_Expression::EV_enum)
{
// CONVENTION: indicates enum discriminant.
return this->lookup_enum (branch);
}
return this->lookup_label (branch);
}
return 0;
}
// Return the default value.
int
AST_Union::default_value (AST_Union::DefaultValue &dv)
{
if (this->default_value_.computed_ == -2)
{
// We need to compute it.
if (this->compute_default_value () == -1)
{
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("(%N:%l) AST_Union::")
ACE_TEXT ("default_value - ")
ACE_TEXT ("Error computing ")
ACE_TEXT ("default value\n")),
-1);
}
}
dv = this->default_value_;
return 0;
}
// Determine the default value (if any).
int
AST_Union::compute_default_value (void)
{
// Check if we really need a default value. This will be true if there is an
// explicit default case OR if an implicit default exists because not all
// values of the discriminant type are covered by the cases.
// Compute the total true "case" labels i.e., exclude the "default" case.
int total_case_members = 0;
// Instantiate a scope iterator.
for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls);
!si.is_done ();
si.next ())
{
// Get the next AST decl node.
AST_UnionBranch *ub =
AST_UnionBranch::narrow_from_decl (si.item ());
if (ub != 0)
{
// If the label is a case label, increment by 1.
for (unsigned long i = 0; i < ub->label_list_length (); ++i)
{
if (ub->label (i)->label_kind () == AST_UnionLabel::UL_label)
{
++total_case_members;
}
}
}
}
// Check if the total_case_members cover the entire
// range of values that are permitted by the discriminant type. If they do,
// then a default value is not necessary. However, if such an explicit
// default case is provided, it must be flagged off as an error. Our
// front-end is not able to handle such a case since it is a semantic error
// and not a syntax error. Such an error is caught here.
switch (this->udisc_type ())
{
case AST_Expression::EV_short:
case AST_Expression::EV_ushort:
if (total_case_members == ACE_UINT16_MAX + 1)
{
this->default_value_.computed_ = 0;
}
break;
case AST_Expression::EV_long:
case AST_Expression::EV_ulong:
if ((unsigned int) total_case_members > ACE_UINT32_MAX)
{
this->default_value_.computed_ = 0;
}
break;
case AST_Expression::EV_longlong:
case AST_Expression::EV_ulonglong:
// Error for now.
this->default_value_.computed_ = -1;
ACE_ERROR_RETURN ((
LM_ERROR,
ACE_TEXT ("(%N:%l) AST_Union::compute_default_value ")
ACE_TEXT ("- unimplemented discriminant type ")
ACE_TEXT ("(longlong or ulonglong)\n")
),
-1
);
ACE_NOTREACHED (break;)
case AST_Expression::EV_char:
if (total_case_members == ACE_OCTET_MAX + 1)
{
this->default_value_.computed_ = 0;
}
break;
case AST_Expression::EV_wchar:
if (total_case_members == ACE_WCHAR_MAX + 1)
{
this->default_value_.computed_ = 0;
}
break;
case AST_Expression::EV_bool:
if (total_case_members == 2)
{
this->default_value_.computed_ = 0;
}
break;
case AST_Expression::EV_enum:
// Has to be enum.
{
AST_Decl *d = AST_Decl::narrow_from_decl (this->disc_type ());
if (d->node_type () == AST_Decl::NT_typedef)
{
AST_Typedef *bt = AST_Typedef::narrow_from_decl (d);
d = bt->primitive_base_type ();
}
AST_Enum *en = AST_Enum::narrow_from_decl (d);
if (en != 0)
{
if (total_case_members == en->member_count ())
{
this->default_value_.computed_ = 0;
}
}
else
{
// Error.
this->default_value_.computed_ = -1;
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("(%N:%l) AST_Union::")
ACE_TEXT ("compute_default_value ")
ACE_TEXT ("- disc type not an ENUM\n")),
-1);
}
}
break;
default:
// Error.
this->default_value_.computed_ = -1;
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("(%N:%l) AST_Union::compute_default_value")
ACE_TEXT (" - Bad discriminant type\n")),
-1);
ACE_NOTREACHED (break;)
} // End of switch
// If we have determined that we don't need a default case and even then a
// default case was provided, flag this off as error.
if ((this->default_value_.computed_ == 0)
&& (this->default_index () != -1))
{
// Error.
this->default_value_.computed_ = -1;
ACE_ERROR_RETURN ((LM_ERROR,
ACE_TEXT ("(%N:%l) AST_Union::compute_default_value")
ACE_TEXT (" - default clause is invalid here\n")),
-1);
}
// Proceed only if necessary.
switch (this->default_value_.computed_)
{
case -1:
// Error. We should never be here because errors
// have already been caught
// above.
return -1;
case 0:
// Nothing more to do.
return 0;
default:
// Proceed further down.
break;
}
// Initialization of the default value data member.
switch (this->udisc_type ())
{
case AST_Expression::EV_short:
this->default_value_.u.short_val = ACE_INT16_MIN;
break;
case AST_Expression::EV_ushort:
this->default_value_.u.ushort_val = 0;
break;
case AST_Expression::EV_long:
// The +1 is to avert a warning on many compilers.
this->default_value_.u.long_val = ACE_INT32_MIN + 1;
break;
case AST_Expression::EV_ulong:
this->default_value_.u.ulong_val = 0;
break;
case AST_Expression::EV_char:
this->default_value_.u.char_val = 0;
break;
case AST_Expression::EV_wchar:
this->default_value_.u.wchar_val = 0;
break;
case AST_Expression::EV_bool:
this->default_value_.u.bool_val = 0;
break;
case AST_Expression::EV_enum:
this->default_value_.u.enum_val = 0;
break;
case AST_Expression::EV_longlong:
case AST_Expression::EV_ulonglong:
// Unimplemented.
default:
// Error caught earlier.
break;
}
// Proceed until we have found the appropriate default value.
while (this->default_value_.computed_ == -2)
{
int break_loop = 0;
// Instantiate a scope iterator.
for (UTL_ScopeActiveIterator si (this, UTL_Scope::IK_decls);
!si.is_done () && break_loop == 0;
si.next ())
{
// Get the next AST decl node
AST_UnionBranch *ub =
AST_UnionBranch::narrow_from_decl (si.item ());
if (ub != 0)
{
for (unsigned long i = 0;
i < ub->label_list_length () && !break_loop;
++i)
{
if (ub->label (i)->label_kind () == AST_UnionLabel::UL_label)
{
// Not a default.
AST_Expression *expr = ub->label (i)->label_val ();
if (expr == 0)
{
// Error.
this->default_value_.computed_ = -1;
ACE_ERROR_RETURN ((
LM_ERROR,
ACE_TEXT ("(%N:%l) AST_Union::")
ACE_TEXT ("compute_default_value - ")
ACE_TEXT ("Bad case label value\n")
),
-1
);
}
switch (expr->ev ()->et)
{
// Check if they match in which case this
// cannot be the implicit default value. So
// start with a new value and try the whole loop
// again because our case labels may not be sorted.
case AST_Expression::EV_short:
if (this->default_value_.u.short_val
== expr->ev ()->u.sval)
{
this->default_value_.u.short_val++;
break_loop = 1;
}
break;
case AST_Expression::EV_ushort:
if (this->default_value_.u.ushort_val
== expr->ev ()->u.usval)
{
this->default_value_.u.ushort_val++;
break_loop = 1;
}
break;
case AST_Expression::EV_long:
if (this->default_value_.u.long_val
== expr->ev ()->u.lval)
{
this->default_value_.u.long_val++;
break_loop = 1;
}
break;
case AST_Expression::EV_ulong:
if (this->default_value_.u.ulong_val
== expr->ev ()->u.ulval)
{
this->default_value_.u.ulong_val++;
break_loop = 1;
}
break;
case AST_Expression::EV_char:
if (this->default_value_.u.char_val
== expr->ev ()->u.cval)
{
this->default_value_.u.char_val++;
break_loop = 1;
}
break;
case AST_Expression::EV_wchar:
if (this->default_value_.u.wchar_val
== expr->ev ()->u.wcval)
{
this->default_value_.u.wchar_val++;
break_loop = 1;
}
break;
case AST_Expression::EV_bool:
if (this->default_value_.u.bool_val
== expr->ev ()->u.bval)
{
this->default_value_.u.bool_val++;
break_loop = 1;
}
break;
case AST_Expression::EV_enum:
// this is the case of enums. We maintain
// evaluated values which always start with 0
if (this->default_value_.u.enum_val
== expr->ev ()->u.eval)
{
this->default_value_.u.enum_val++;
break_loop = 1;
}
break;
case AST_Expression::EV_longlong:
case AST_Expression::EV_ulonglong:
// Unimplemented. right now - flag as error.
default:
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?