Beispiel #1
0
static struct block_symbol
cp_lookup_symbol_via_imports (const char *scope,
			      const char *name,
			      const struct block *block,
			      const domain_enum domain,
			      const int search_scope_first,
			      const int declaration_only,
			      const int search_parents)
{
  struct using_direct *current;
  struct block_symbol sym;
  int len;
  int directive_match;
  struct cleanup *searched_cleanup;

  sym.symbol = NULL;
  sym.block = NULL;

  /* First, try to find the symbol in the given namespace if requested.  */
  if (search_scope_first)
    sym = cp_lookup_symbol_in_namespace (scope, name,
					 block, domain, 1);

  if (sym.symbol != NULL)
    return sym;

  /* Go through the using directives.  If any of them add new names to
     the namespace we're searching in, see if we can find a match by
     applying them.  */

  for (current = block_using (block);
       current != NULL;
       current = current->next)
    {
      const char **excludep;

      len = strlen (current->import_dest);
      directive_match = (search_parents
                         ? (startswith (scope, current->import_dest)
                            && (len == 0
                                || scope[len] == ':'
				|| scope[len] == '\0'))
                         : strcmp (scope, current->import_dest) == 0);

      /* If the import destination is the current scope or one of its
         ancestors then it is applicable.  */
      if (directive_match && !current->searched)
	{
	  /* Mark this import as searched so that the recursive call
	     does not search it again.  */
	  current->searched = 1;
	  searched_cleanup = make_cleanup (reset_directive_searched,
					   current);

	  /* If there is an import of a single declaration, compare the
	     imported declaration (after optional renaming by its alias)
	     with the sought out name.  If there is a match pass
	     current->import_src as NAMESPACE to direct the search
	     towards the imported namespace.  */
	  if (current->declaration
	      && strcmp (name, current->alias
			 ? current->alias : current->declaration) == 0)
	    sym = cp_lookup_symbol_in_namespace (current->import_src,
						 current->declaration,
						 block, domain, 1);

	  /* If this is a DECLARATION_ONLY search or a symbol was found
	     or this import statement was an import declaration, the
	     search of this import is complete.  */
	  if (declaration_only || sym.symbol != NULL || current->declaration)
	    {
	      current->searched = 0;
	      discard_cleanups (searched_cleanup);

	      if (sym.symbol != NULL)
		return sym;

	      continue;
	    }

	  /* Do not follow CURRENT if NAME matches its EXCLUDES.  */
	  for (excludep = current->excludes; *excludep; excludep++)
	    if (strcmp (name, *excludep) == 0)
	      break;
	  if (*excludep)
	    {
	      discard_cleanups (searched_cleanup);
	      continue;
	    }

	  if (current->alias != NULL
	      && strcmp (name, current->alias) == 0)
	    /* If the import is creating an alias and the alias matches
	       the sought name.  Pass current->import_src as the NAME to
	       direct the search towards the aliased namespace.  */
	    {
	      sym = cp_lookup_symbol_in_namespace (scope,
						   current->import_src,
						   block, domain, 1);
	    }
	  else if (current->alias == NULL)
	    {
	      /* If this import statement creates no alias, pass
		 current->inner as NAMESPACE to direct the search
		 towards the imported namespace.  */
	      sym = cp_lookup_symbol_via_imports (current->import_src,
						  name, block,
						  domain, 1, 0, 0);
	    }
	  current->searched = 0;
	  discard_cleanups (searched_cleanup);

	  if (sym.symbol != NULL)
	    return sym;
	}
    }

  return null_block_symbol;
}
Beispiel #2
0
static struct block_symbol
d_lookup_symbol_imports (const char *scope, const char *name,
			 const struct block *block,
			 const domain_enum domain)
{
  struct using_direct *current;
  struct block_symbol sym;
  struct cleanup *searched_cleanup;

  /* First, try to find the symbol in the given module.  */
  sym = d_lookup_symbol_in_module (scope, name, block, domain, 1);

  if (sym.symbol != NULL)
    return sym;

  /* Go through the using directives.  If any of them add new names to
     the module we're searching in, see if we can find a match by
     applying them.  */

  for (current = block_using (block);
       current != NULL;
       current = current->next)
    {
      const char **excludep;

      /* If the import destination is the current scope then search it.  */
      if (!current->searched && strcmp (scope, current->import_dest) == 0)
	{
	  /* Mark this import as searched so that the recursive call
	     does not search it again.  */
	  current->searched = 1;
	  searched_cleanup = make_cleanup (reset_directive_searched,
					   current);

	  /* If there is an import of a single declaration, compare the
	     imported declaration (after optional renaming by its alias)
	     with the sought out name.  If there is a match pass
	     current->import_src as MODULE to direct the search towards
	     the imported module.  */
	  if (current->declaration
	      && strcmp (name, current->alias
			 ? current->alias : current->declaration) == 0)
	    sym = d_lookup_symbol_in_module (current->import_src,
					     current->declaration,
					     block, domain, 1);

	  /* If a symbol was found or this import statement was an import
	     declaration, the search of this import is complete.  */
	  if (sym.symbol != NULL || current->declaration)
	    {
	      current->searched = 0;
	      discard_cleanups (searched_cleanup);

	      if (sym.symbol != NULL)
		return sym;

	      continue;
	    }

	  /* Do not follow CURRENT if NAME matches its EXCLUDES.  */
	  for (excludep = current->excludes; *excludep; excludep++)
	    if (strcmp (name, *excludep) == 0)
	      break;
	  if (*excludep)
	    {
	      discard_cleanups (searched_cleanup);
	      continue;
	    }

	  /* If the import statement is creating an alias.  */
	  if (current->alias != NULL)
	    {
	      if (strcmp (name, current->alias) == 0)
		{
		  /* If the alias matches the sought name.  Pass
		     current->import_src as the NAME to direct the
		     search towards the aliased module.  */
		  sym = lookup_module_scope (NULL, current->import_src, block,
					     domain, scope, 0);
		}
	      else
		{
		  /* If the alias matches the first component of the
		     sought name, pass current->import_src as MODULE
		     to direct the search, skipping over the aliased
		     component in NAME.  */
		  int name_scope = d_find_first_component (name);

		  if (name[name_scope] != '\0'
		      && strncmp (name, current->alias, name_scope) == 0)
		    {
		      /* Skip the '.'  */
		      name_scope++;
		      sym = d_lookup_symbol_imports (current->import_src,
						     name + name_scope,
						     block, domain);
		    }
		}
	    }
	  else
	    {
	      /* If this import statement creates no alias, pass
		 current->import_src as MODULE to direct the search
		 towards the imported module.  */
	      sym = d_lookup_symbol_imports (current->import_src,
					     name, block, domain);
	    }
	  current->searched = 0;
	  discard_cleanups (searched_cleanup);

	  if (sym.symbol != NULL)
	    return sym;
	}
    }

  return null_block_symbol;
}