utl_scope.cpp

来自「这是广泛使用的通信开源项目,对于大容量,高并发的通讯要求完全能够胜任,他广泛可用」· C++ 代码 · 共 2,436 行 · 第 1/4 页

CPP
2,436
字号
                      UTL_ScopeActiveIterator (
                              idl_global->scopes ().bottom (),
                              UTL_Scope::IK_decls),
                      0);
    }
  else if (ACE_OS::strcasecmp (name_string, "TypeCode") == 0
           || ACE_OS::strcasecmp (name_string, "TCKind") == 0)
    {
      // Occurrences of "TypeCode" or TCKind in IDL files must be
      // scoped with "CORBA" so we know we'll be in the CORBA module
      // if we get this far, and we can use "this" for the scope of
      // the iterator.
      ACE_NEW_RETURN (i,
                      UTL_ScopeActiveIterator (this,
                                               UTL_Scope::IK_decls),
                      0);
      tc_lookup = I_TRUE;
    }
  else
    {
      return 0;
    }

  for (; !i->is_done (); i->next ())
    {
      d = i->item ();

      item_name = d->local_name ();

      if (e->case_compare (item_name))
        {
          delete i;

          // These have to be located here because we are just looking
          // up a scoped name - skip for imported nodes.
          if (idl_global->in_main_file ())
            {
              if (tc_lookup)
                {
                  // Generation of #includes for Typecode.h
                  // checks this bit, so we set it for TCKind as well.
                  ACE_SET_BITS (idl_global->decls_seen_info_,
                                idl_global->decls_seen_masks.typecode_seen_);
                }
              else if (obj_lookup)
                {
                  ACE_SET_BITS (idl_global->decls_seen_info_,
                                idl_global->decls_seen_masks.base_object_seen_);
                }
              else if (vb_lookup)
                {
                  ACE_SET_BITS (idl_global->decls_seen_info_,
                                idl_global->decls_seen_masks.valuetype_seen_);
                }
            }

          return d;
        }
    }

  if (tc_lookup)
    {
      d = this->look_in_previous (e);

      if (d != 0)
        {
          // Generation of #includes for Typecode.h
          // checks this bit, so we set it for TCKind as well.
          ACE_SET_BITS (idl_global->decls_seen_info_,
                        idl_global->decls_seen_masks.typecode_seen_);
          delete i;
          return d;
        }
    }

  delete i;
  return 0;
}

AST_Decl *
UTL_Scope::look_in_previous (Identifier *)
{
  return 0;
}

// Lookup the node for a primitive (built in) type.
AST_Decl *
UTL_Scope::lookup_primitive_type (AST_Expression::ExprType et)
{
  AST_PredefinedType::PredefinedType pdt;

  AST_Decl *as_decl = ScopeAsDecl (this);

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

  UTL_Scope *ancestor = as_decl->defined_in ();

  if (ancestor != 0)
    {
      return ancestor->lookup_primitive_type (et);
    }

  switch (et)
    {
    case AST_Expression::EV_short:
      pdt = AST_PredefinedType::PT_short;
      break;
    case AST_Expression::EV_ushort:
      pdt = AST_PredefinedType::PT_ushort;
      break;
    case AST_Expression::EV_long:
      pdt = AST_PredefinedType::PT_long;
      break;
    case AST_Expression::EV_ulong:
      pdt = AST_PredefinedType::PT_ulong;
      break;
    case AST_Expression::EV_longlong:
      pdt = AST_PredefinedType::PT_longlong;
      break;
    case AST_Expression::EV_ulonglong:
      pdt = AST_PredefinedType::PT_ulonglong;
      break;
    case AST_Expression::EV_float:
      pdt = AST_PredefinedType::PT_float;
      break;
    case AST_Expression::EV_double:
      pdt = AST_PredefinedType::PT_double;
      break;
    case AST_Expression::EV_longdouble:
      pdt = AST_PredefinedType::PT_longdouble;
      break;
    case AST_Expression::EV_char:
      pdt = AST_PredefinedType::PT_char;
      break;
    case AST_Expression::EV_wchar:
      pdt = AST_PredefinedType::PT_wchar;
      break;
    case AST_Expression::EV_octet:
      pdt = AST_PredefinedType::PT_octet;
      break;
    case AST_Expression::EV_bool:
      pdt = AST_PredefinedType::PT_boolean;
      break;
    case AST_Expression::EV_any:
      pdt = AST_PredefinedType::PT_any;
      break;
    case AST_Expression::EV_object:
      pdt = AST_PredefinedType::PT_object;
      break;
    case AST_Expression::EV_void:
      pdt = AST_PredefinedType::PT_void;
      break;
    case AST_Expression::EV_enum:
    case AST_Expression::EV_string:
    case AST_Expression::EV_wstring:
    case AST_Expression::EV_none:
    default:
      return 0;
    }

  AST_PredefinedType *t = 0;

  for (UTL_ScopeActiveIterator i (this, UTL_Scope::IK_decls);
       !i.is_done();
       i.next ())
    {
      as_decl = i.item ();

      if (as_decl->node_type () == AST_Decl::NT_pre_defined)
        {
          t = AST_PredefinedType::narrow_from_decl (as_decl);

          if (t == 0)
            {
              continue;
            }

          if (t->pt () == pdt)
            {
              if (idl_global->in_main_file ())
                {
                  switch (pdt)
                    {
                      case AST_PredefinedType::PT_any:
                        ACE_SET_BITS (idl_global->decls_seen_info_,
                                      idl_global->decls_seen_masks.any_seen_);
                        break;
                      case AST_PredefinedType::PT_object:
                        ACE_SET_BITS (
                            idl_global->decls_seen_info_,
                            idl_global->decls_seen_masks.base_object_seen_
                          );
                        break;
                      default:
                        break;
                    }
                }

              return t;
            }
        }
    }

  return 0;
}

// Look through inherited interfaces.
AST_Decl *
UTL_Scope::look_in_inherited (UTL_ScopedName *e,
                              idl_bool treat_as_ref)
{
  AST_Decl *d = 0;
  AST_Decl *d_before = 0;
  AST_Interface *i = AST_Interface::narrow_from_scope (this);
  AST_Interface **is = 0;
  long nis = -1;

  // This scope is not an interface.
  if (i == 0)
    {
      return 0;
    }

  // Can't look in an interface which was not yet defined.
  if (!i->is_defined ())
    {
      idl_global->err ()->fwd_decl_lookup (i,
                                           e);
      return 0;
    }

  // OK, loop through inherited interfaces.

  // (Don't leave the inheritance hierarchy, no module or global ...)
  // Find all and report ambiguous results as error.

  for (nis = i->n_inherits (), is = i->inherits (); nis > 0; nis--, is++)
    {
      d = (*is)->lookup_by_name (e,
                                 treat_as_ref,
                                 0 /* not in parent */);
      if (d != 0)
        {
          if (d_before == 0)
            {
              // First result found.
              d_before = d;
            }
          else
            {
              // Conflict against further results?
              if (d != d_before)
                {
                  ACE_ERROR ((LM_ERROR,
                              "warning in %s line %d: ",
                              idl_global->filename ()->get_string (),
                              idl_global->lineno ()));

                  e->dump (*ACE_DEFAULT_LOG_STREAM);

                  ACE_ERROR ((LM_ERROR,
                              " is ambiguous in scope.\n"
                              "Found "));

                  d->name ()->dump (*ACE_DEFAULT_LOG_STREAM);

                  ACE_ERROR ((LM_ERROR,
                              " and "));

                  d_before->name ()->dump (*ACE_DEFAULT_LOG_STREAM);

                  ACE_ERROR ((LM_ERROR,
                              ".\n"));
                }
            }
        }
    }

  return d_before;
}

// Look up a String * in local scope only.
AST_Decl *
UTL_Scope::lookup_by_name_local (Identifier *e,
                                 long index)
{
  if (index > 0 && index == (long) this->nmembers ())
    {
      return 0;
    }

  // Will return 0 unless looking up 'Object' or 'TypeCode'.
  AST_Decl *d = this->lookup_pseudo (e);

  if (d != 0)
    {
      return d;
    }

  if (this->idl_keyword_clash (e) != 0)
    {
      return 0;
    }

  Identifier *item_name = 0;

  idl_bool in_corba =
    ACE_OS::strcmp (e->get_string (), "CORBA") == 0;

  // Iterate over this scope.
  for (UTL_ScopeActiveIterator i (this, UTL_Scope::IK_both);
       !i.is_done ();
       i.next ())
    {
      d = i.item ();

      item_name = d->local_name ();

      if (item_name == 0)
        {
          continue;
        }

      // Right now we populate the global scope with all the CORBA basic
      // types, so something like 'ULong' in an IDL file will find a
      // match, unless we skip over these items. This is a workaround until
      // there's time to fix the code generation for CORBA basic types.
      if (!in_corba
          && ACE_OS::strcmp (d->name ()->head ()->get_string (), "CORBA") == 0)
        {
          continue;
        }

      if (e->case_compare (item_name))
        {
          if (index == 0)
            {
              AST_Decl::NodeType nt = d->node_type ();

              // Special case for forward declared interfaces,
              // In this case, we want to return
              // the full definition member, whether defined yet or not
              if (nt == AST_Decl::NT_interface_fwd
                  || nt == AST_Decl::NT_valuetype_fwd
                  || nt == AST_Decl::NT_component_fwd)
                {
                  d = AST_InterfaceFwd::narrow_from_decl (d)->full_definition ();
                }
              else if (nt == AST_Decl::NT_struct_fwd
                       || nt == AST_Decl::NT_union_fwd)
                {
                  d = AST_StructureFwd::narrow_from_decl (d)->full_definition ();
                }

              return d;
            }
          else
          // If the index has been incremented, it means the identifier
          // matched on a previous call to this function, but after
          // returning, the rest of the scoped name didn't match. So we
          // see if there's another matching identifier to the 'head' of
          // the scoped name we're working with.
            {
              index--;
              continue;
            }
        }
    }

  // OK, not found, check if this scope is a module, and if so,
  // look in previous openings, if any.
  d = ScopeAsDecl (this);

  if (d->node_type () == AST_Decl::NT_module)
    {
      AST_Module *m = AST_Module::narrow_from_decl (d);

      return m->look_in_previous (e);
    }
  else
    {
      return 0;
    }
}

// Implements lookup by name for scoped names.
AST_Decl *
UTL_Scope::lookup_by_name (UTL_ScopedName *e,
                           idl_bool treat_as_ref,
                           idl_bool in_parent)
{
  AST_Decl *d = 0;
  UTL_Scope *t = 0;

  // Empty name? Error.
  if (e == 0)
    {
      return 0;
    }

  // If name starts with "::" or "" start lookup in global scope.
  if (is_global_name (e->head ()))
    {
     // Get parent scope.
      d = ScopeAsDecl (this);

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

      t = d->defined_in ();

      // If this is the global scope..
      if (t == 0)
        {
          // Look up tail of name starting here.
          d = lookup_by_name ((UTL_ScopedName *) e->tail (),
                              treat_as_ref,
                              in_parent);

          // Now return whatever we have.
          return d;
        }

      // OK, not global scope yet, so simply iterate with parent scope.
      d = t->lookup_by_name (e,
                             treat_as_ref,
                             in_parent);

      // If treat_as_ref is true and d is not NULL, add d to
      // set of nodes referenced here.
      if (treat_as_ref && d != 0)
        {
          add_to_referenced (d,
                             I_FALSE,
                             0);
        }

      // Now return what we have.
      return d;
    }

  // The name does not start with "::"
  // Is name defined here?
  long index = 0;

  while (1)
    {
      d = lookup_by_name_local (e->head (),
                                index);

      if (d == 0)
        {

          // Special case for scope which is an interface or value type.
          // We have to look in the inherited interfaces as well.
          // Look before parent scopes.
          if (pd_scope_node_type == AST_Decl::NT_interface
              || pd_scope_node_type == AST_Decl::NT_valuetype
              || pd_scope_node_type == AST_Decl::NT_component
              || pd_scope_node_type == AST_Decl::NT_eventtype)
            {
              d = look_in_inherited (e,
                                     treat_as_ref);
            }

          if ((d == 0) && in_parent && idl_global->err_count () == 0)
            {

              // OK, not found. Go down parent scope chain.
              d = ScopeAsDecl (this);

              if (d != 0)
                {
                  t = d->defined_in ();

                  if (t == 0)
                    {
                      d = 0;
                    }
                  else
                    {
                      d = t->lookup_by_name (e,
                                             treat_as_ref,
                                             in_parent);
                    }
                }
            }

          // If treat_as_ref is true and d is not NULL, add d to
          // set of nodes referenced here.
          if (treat_as_ref && d != 0)
            {
              AST_Type *t = AST_Type::narrow_from_decl (d);

              // Are we a type, rather than an identifier?
              if (t != 0)
                {
                  // Are we defined in this scope or just referenced?
                  if (d->defined_in () == this)
                    {
                      UTL_Scope *s = ScopeAsDecl (this)->defined_in ();

                      if (s != 0)
                        {
                          AST_Decl *parent = ScopeAsDecl (s);
                          AST_Decl::NodeType nt = parent->node_type ();

                          // If the scope we are defined in is itself
                          // inside a module, then we should also
                          // be exported to the enclosing scope,
                          // recursive until we get to the enclosing
                          // module (or root) scope. (CORBA 2.6 3.15.3).
                          while (nt != AST_Decl::NT_module
                                 && nt != AST_Decl::NT_root)
                            {
                              s->add_to_referenced (d,
                                                    I_FALSE,
                                                    d->local_name ());

                              s = parent->defined_in ();
                              parent = ScopeAsDecl (s);
                              nt = parent->node_type ();
                            }
                        }
                    }
                }
            }

          // OK, now return whatever we found.
          return d;
        }

      // For the possible call to look_in_inherited() below.
      AST_Decl::NodeType nt = d->node_type ();
      t = DeclAsScope (d);

      // OK, start of name is defined. Now loop doing local lookups
      // of subsequent elements of the name, if any.
      UTL_ScopedName *sn = (UTL_ScopedName *) e->tail ();

      if (sn != 0)
        {
          d = iter_lookup_by_name_local (d,
                                         sn,
                                         0);
        }

      // If the start of the scoped name is an interface, and the
      // above lookup failed, it's possible that what we're looking
      // up was inherited into that interface. The first call to
      // look_in_inherited() is this function only checks base classes
      // of the scope (interface) we started the lookup from.
      if (d == 0 && nt == AST_Decl::NT_interface)
        {
          d = t->look_in_inherited (sn,
                                    treat_as_ref);
        }

      // If treat_as_ref is true and d is not 0, add d to
      // set of nodes referenced here.
      if (treat_as_ref && d != 0)
        {
          add_to_referenced (d,
                             I_FALSE,
                             0);
        }

      // All OK, name fully resolved.
      if (d != 0)
        {
          return d;
        }
      else
        {
          index++;
        }
    }
}

// Add a node to set of nodes referenced in this scope.
void
UTL_Scope::add_to_referenced (AST_Decl *e,
                              idl_bool recursive,
                              Identifier *id,
                              AST_Decl *ex)
{
  UTL_Scope *s = 0;
  AST_Decl **tmp;
  AST_Interface *itf = 0;
  long oreferenced_allocated;
  long i;

  if (e == 0)
    {
      return;
    }

  // Special case for forward declared interfaces in the
  // scope in which they're defined. Cannot add before full
  // definition is seen.
  if (e->node_type () == AST_Decl::NT_interface)
    {
      itf = AST_Interface::narrow_from_decl(e);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?