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 + -
显示快捷键?