Example #1
0
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;
}
Example #2
0
// Look up a branch in an enum which is the discriminator type for this
// union, based on the label value which must be an enumerator in that
// enum.
AST_UnionBranch *
AST_Union::lookup_enum (AST_UnionBranch *b)
{
  AST_UnionLabel *label = b->label();
  AST_Expression *lv = label->label_val ();
  AST_Enum *e = AST_Enum::narrow_from_decl (this->pd_disc_type);
  AST_Decl *d = 0;
  AST_UnionBranch       *fb = 0;

  if (e == 0)
    {
      return 0;
    }

  if (lv == 0)
    {
      return b;
    }

  // Expecting a symbol label.
  if (lv->ec () != AST_Expression::EC_symbol)
    {
      idl_global->err ()->enum_val_expected (this,
                                             label);
      return b;
    }

  // See if the symbol defines a constant in the discriminator enum.
  UTL_ScopedName *sn = lv->n ();
  d = e->lookup_by_name (sn,
                         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;
}