*** empty log message ***
[binutils-gdb.git] / gdb / cp-namespace.c
index e04246367194955876deae7b52dc8f00c4c2f2fa..16f58ca1a3cf84d49302226d674f508ba153b4fa 100644 (file)
@@ -32,6 +32,7 @@
 #include "command.h"
 #include "frame.h"
 #include "buildsym.h"
+#include "language.h"
 
 static struct symbol *lookup_namespace_scope (const char *name,
                                              const struct block *block,
@@ -81,7 +82,6 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
       const char *name = SYMBOL_DEMANGLED_NAME (symbol);
       unsigned int previous_component;
       unsigned int next_component;
-      const char *len;
 
       /* Start with a quick-and-dirty check for mention of "(anonymous
         namespace)".  */
@@ -265,6 +265,7 @@ cp_lookup_symbol_in_namespace (const char *namespace,
     {
       char *concatenated_name = alloca (strlen (namespace) + 2 +
                                         strlen (name) + 1);
+
       strcpy (concatenated_name, namespace);
       strcat (concatenated_name, "::");
       strcat (concatenated_name, name);
@@ -412,6 +413,95 @@ cp_lookup_symbol_imports (const char *scope,
   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)
+    {
+      int i;
+      struct cplus_specific *cps
+       = function->ginfo.language_specific.cplus_specific;
+
+      /* 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.  */
@@ -578,10 +668,24 @@ cp_lookup_nested_type (struct type *parent_type,
                                                            nested_name,
                                                            block,
                                                            VAR_DOMAIN);
-       if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF)
-         return NULL;
-       else
+       char *concatenated_name;
+
+       if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
+         return SYMBOL_TYPE (sym);
+
+       /* Now search all static file-level symbols.  Not strictly correct,
+          but more useful than an error.  We do not try to guess any imported
+          namespace as even the fully specified namespace seach is is already
+          not C++ compliant and more assumptions could make it too magic.  */
+
+       concatenated_name = alloca (strlen (parent_name) + 2
+                                   + strlen (nested_name) + 1);
+       sprintf (concatenated_name, "%s::%s", parent_name, nested_name);
+       sym = lookup_static_symbol_aux (concatenated_name, VAR_DOMAIN);
+       if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
          return SYMBOL_TYPE (sym);
+
+       return NULL;
       }
     default:
       internal_error (__FILE__, __LINE__,
@@ -645,6 +749,7 @@ cp_lookup_transparent_type_loop (const char *name, const char *scope,
     {
       struct type *retval
        = cp_lookup_transparent_type_loop (name, scope, scope_length + 2);
+
       if (retval != NULL)
        return retval;
     }
@@ -833,7 +938,7 @@ check_one_possible_namespace_symbol (const char *name, int len,
 
       sym = obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol));
       memset (sym, 0, sizeof (struct symbol));
-      SYMBOL_LANGUAGE (sym) = language_cplus;
+      SYMBOL_SET_LANGUAGE (sym, language_cplus);
       /* Note that init_type copied the name to the objfile's
         obstack.  */
       SYMBOL_SET_NAMES (sym, TYPE_NAME (type), len, 0, objfile);
@@ -877,6 +982,7 @@ static void
 maintenance_cplus_namespace (char *args, int from_tty)
 {
   struct objfile *objfile;
+
   printf_unfiltered (_("Possible namespaces:\n"));
   ALL_OBJFILES (objfile)
     {