+struct block_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);
+ struct block_symbol result;
+
+ if (symbol_lookup_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "cp_lookup_symbol_imports_or_template"
+ " (%s, %s, %s, %s)\n",
+ scope, name, host_address_to_string (block),
+ domain_name (domain));
+ }
+
+ if (function != NULL && function->language () == 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 *sym = search_symbol_list (name,
+ templ->n_template_arguments,
+ templ->template_arguments);
+
+ if (sym != NULL)
+ {
+ if (symbol_lookup_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "cp_lookup_symbol_imports_or_template"
+ " (...) = %s\n",
+ host_address_to_string (sym));
+ }
+ return (struct block_symbol) {sym, block};
+ }
+ }
+
+ /* Search the template parameters of the function's defining
+ context. */
+ if (function->natural_name ())
+ {
+ struct type *context;
+ std::string name_copy (function->natural_name ());
+ const struct language_defn *lang = language_def (language_cplus);
+ const struct block *parent = BLOCK_SUPERBLOCK (block);
+ struct symbol *sym;
+
+ while (1)
+ {
+ unsigned int prefix_len
+ = cp_entire_prefix_len (name_copy.c_str ());
+
+ if (prefix_len == 0)
+ context = NULL;
+ else
+ {
+ name_copy.erase (prefix_len);
+ context = lookup_typename (lang,
+ name_copy.c_str (),
+ parent, 1);
+ }
+
+ if (context == NULL)
+ break;
+
+ sym
+ = search_symbol_list (name,
+ TYPE_N_TEMPLATE_ARGUMENTS (context),
+ TYPE_TEMPLATE_ARGUMENTS (context));
+ if (sym != NULL)
+ {
+ if (symbol_lookup_debug)
+ {
+ fprintf_unfiltered
+ (gdb_stdlog,
+ "cp_lookup_symbol_imports_or_template (...) = %s\n",
+ host_address_to_string (sym));
+ }
+ return (struct block_symbol) {sym, parent};
+ }
+ }
+ }
+ }
+
+ result = cp_lookup_symbol_via_imports (scope, name, block, domain, 0, 1, 1);
+ if (symbol_lookup_debug)
+ {
+ fprintf_unfiltered (gdb_stdlog,
+ "cp_lookup_symbol_imports_or_template (...) = %s\n",
+ result.symbol != NULL
+ ? host_address_to_string (result.symbol) : "NULL");
+ }
+ return result;
+}
+
+/* Search for NAME 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. */
+
+static struct block_symbol
+cp_lookup_symbol_via_all_imports (const char *scope, const char *name,
+ const struct block *block,
+ const domain_enum domain)
+{
+ struct block_symbol sym;
+
+ while (block != NULL)
+ {
+ sym = cp_lookup_symbol_via_imports (scope, name, block, domain, 0, 0, 1);
+ if (sym.symbol)
+ return sym;
+
+ block = BLOCK_SUPERBLOCK (block);
+ }
+
+ return {};
+}
+
+/* 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 block_symbol