+ struct symbol *sym;
+ const char *scope = block_scope (block);
+
+ sym = lookup_namespace_scope (name, block,
+ domain, scope, 0);
+ if (sym != NULL)
+ return sym;
+
+ return cp_lookup_symbol_namespace (scope, name,
+ block, domain);
+}
+
+/* Look up NAME in the C++ namespace NAMESPACE. Other arguments are
+ as in cp_lookup_symbol_nonlocal. If SEARCH is non-zero, search
+ through base classes for a matching symbol. */
+
+static struct symbol *
+cp_lookup_symbol_in_namespace (const char *namespace,
+ const char *name,
+ const struct block *block,
+ const domain_enum domain, int search)
+{
+ if (namespace[0] == '\0')
+ {
+ return lookup_symbol_file (name, block, domain, 0, search);
+ }
+ else
+ {
+ char *concatenated_name = alloca (strlen (namespace) + 2
+ + strlen (name) + 1);
+
+ strcpy (concatenated_name, namespace);
+ strcat (concatenated_name, "::");
+ strcat (concatenated_name, name);
+ return lookup_symbol_file (concatenated_name, block, domain,
+ cp_is_anonymous (namespace), search);
+ }
+}
+
+/* Used for cleanups to reset the "searched" flag incase
+ of an error. */
+
+static void
+reset_directive_searched (void *data)
+{
+ struct using_direct *direct = data;
+ direct->searched = 0;
+}
+
+/* Search for NAME by applying all import statements belonging to
+ BLOCK which are applicable in SCOPE. If DECLARATION_ONLY the
+ search is restricted to using declarations.
+ Example:
+
+ namespace A {
+ int x;
+ }
+ using A::x;
+
+ If SEARCH_PARENTS the search will include imports which are
+ applicable in parents of SCOPE.
+ Example:
+
+ namespace A {
+ using namespace X;
+ namespace B {
+ using namespace Y;
+ }
+ }
+
+ If SCOPE is "A::B" and SEARCH_PARENTS is true the imports of
+ namespaces X and Y will be considered. If SEARCH_PARENTS is false
+ only the import of Y is considered. */
+
+struct symbol *
+cp_lookup_symbol_imports (const char *scope,
+ const char *name,
+ const struct block *block,
+ const domain_enum domain,
+ const int declaration_only,
+ const int search_parents)
+{
+ struct using_direct *current;
+ struct symbol *sym = NULL;
+ int len;
+ int directive_match;
+ struct cleanup *searched_cleanup;
+
+ /* First, try to find the symbol in the given namespace. */
+ if (!declaration_only)
+ sym = cp_lookup_symbol_in_namespace (scope, name,
+ block, domain, 1);
+
+ if (sym != 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
+ ? (strncmp (scope, current->import_dest,
+ strlen (current->import_dest)) == 0
+ && (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 != NULL || current->declaration)
+ {
+ current->searched = 0;
+ discard_cleanups (searched_cleanup);
+
+ if (sym != 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_imports (current->import_src,
+ name, block,
+ domain, 0, 0);
+ }
+ current->searched = 0;
+ discard_cleanups (searched_cleanup);
+
+ if (sym != NULL)
+ return sym;
+ }
+ }
+
+ return NULL;
+}
+
+/* Helper function that searches an array of symbols for one named
+ NAME. */
+
+static struct symbol *
+search_symbol_list (const char *name, int num,
+ struct symbol **syms)
+{
+ int i;
+
+ /* Maybe we should store a dictionary in here instead. */
+ for (i = 0; i < num; ++i)
+ {
+ if (strcmp (name, SYMBOL_NATURAL_NAME (syms[i])) == 0)
+ return syms[i];
+ }
+ return NULL;
+}
+
+/* Like cp_lookup_symbol_imports, but if BLOCK is a function, it
+ searches through the template parameters of the function and the
+ function's type. */
+
+struct symbol *
+cp_lookup_symbol_imports_or_template (const char *scope,
+ const char *name,
+ const struct block *block,
+ const domain_enum domain)
+{
+ struct symbol *function = BLOCK_FUNCTION (block);
+
+ if (function != NULL && SYMBOL_LANGUAGE (function) == language_cplus)
+ {
+ /* Search the function's template parameters. */
+ if (SYMBOL_IS_CPLUS_TEMPLATE_FUNCTION (function))
+ {
+ struct template_symbol *templ
+ = (struct template_symbol *) function;
+ struct symbol *result;
+
+ result = search_symbol_list (name,
+ templ->n_template_arguments,
+ templ->template_arguments);
+ if (result != NULL)
+ return result;
+ }
+
+ /* Search the template parameters of the function's defining
+ context. */
+ if (SYMBOL_NATURAL_NAME (function))
+ {
+ struct type *context;
+ char *name_copy = xstrdup (SYMBOL_NATURAL_NAME (function));
+ struct cleanup *cleanups = make_cleanup (xfree, name_copy);
+ const struct language_defn *lang = language_def (language_cplus);
+ struct gdbarch *arch = SYMBOL_SYMTAB (function)->objfile->gdbarch;
+ const struct block *parent = BLOCK_SUPERBLOCK (block);
+
+ while (1)
+ {
+ struct symbol *result;
+ unsigned int prefix_len = cp_entire_prefix_len (name_copy);
+
+ if (prefix_len == 0)
+ context = NULL;
+ else
+ {
+ name_copy[prefix_len] = '\0';
+ context = lookup_typename (lang, arch,
+ name_copy,
+ parent, 1);
+ }
+
+ if (context == NULL)
+ break;
+
+ result
+ = search_symbol_list (name,
+ TYPE_N_TEMPLATE_ARGUMENTS (context),
+ TYPE_TEMPLATE_ARGUMENTS (context));
+ if (result != NULL)
+ return result;
+ }
+
+ do_cleanups (cleanups);
+ }
+ }
+
+ return cp_lookup_symbol_imports (scope, name, block, domain, 1, 1);
+}
+
+ /* Searches for NAME in the current namespace, and by applying
+ relevant import statements belonging to BLOCK and its parents.
+ SCOPE is the namespace scope of the context in which the search is
+ being evaluated. */
+
+struct symbol*
+cp_lookup_symbol_namespace (const char *scope,
+ const char *name,
+ const struct block *block,
+ const domain_enum domain)
+{
+ struct symbol *sym;
+
+ /* First, try to find the symbol in the given namespace. */
+ sym = cp_lookup_symbol_in_namespace (scope, name,
+ block, domain, 1);
+ if (sym != NULL)
+ return sym;
+
+ /* Search for name in namespaces imported to this and parent
+ blocks. */
+ while (block != NULL)
+ {
+ sym = cp_lookup_symbol_imports (scope, name, block,
+ domain, 0, 1);
+
+ if (sym)
+ return sym;
+
+ block = BLOCK_SUPERBLOCK (block);
+ }
+
+ return NULL;