PR symtab/18258
[deliverable/binutils-gdb.git] / gdb / cp-namespace.c
index c58efa44b78aa1012d950ea393e34dbb405d372c..0feeb35ba674ac112f16835aad22122016d92a04 100644 (file)
@@ -1,5 +1,5 @@
 /* Helper routines for C++ support in GDB.
-   Copyright (C) 2003-2014 Free Software Foundation, Inc.
+   Copyright (C) 2003-2015 Free Software Foundation, Inc.
 
    Contributed by David Carlton and by Kealia, Inc.
 
@@ -37,7 +37,7 @@ static struct symbol *
                             const char *nested_name,
                             const char *concatenated_name,
                             const struct block *block,
-                            int basic_lookup);
+                            int basic_lookup, int is_in_anonymous);
 
 static struct type *cp_lookup_transparent_type_loop (const char *name,
                                                     const char *scope,
@@ -126,7 +126,7 @@ cp_add_using_directive (const char *dest,
                         struct obstack *obstack)
 {
   struct using_direct *current;
-  struct using_direct *new;
+  struct using_direct *newobj;
 
   /* Has it already been added?  */
 
@@ -163,39 +163,39 @@ cp_add_using_directive (const char *dest,
       return;
     }
 
-  new = obstack_alloc (obstack, (sizeof (*new)
+  newobj = obstack_alloc (obstack, (sizeof (*newobj)
                                 + (VEC_length (const_char_ptr, excludes)
-                                   * sizeof (*new->excludes))));
-  memset (new, 0, sizeof (*new));
+                                   * sizeof (*newobj->excludes))));
+  memset (newobj, 0, sizeof (*newobj));
 
   if (copy_names)
     {
-      new->import_src = obstack_copy0 (obstack, src, strlen (src));
-      new->import_dest = obstack_copy0 (obstack, dest, strlen (dest));
+      newobj->import_src = obstack_copy0 (obstack, src, strlen (src));
+      newobj->import_dest = obstack_copy0 (obstack, dest, strlen (dest));
     }
   else
     {
-      new->import_src = src;
-      new->import_dest = dest;
+      newobj->import_src = src;
+      newobj->import_dest = dest;
     }
 
   if (alias != NULL && copy_names)
-    new->alias = obstack_copy0 (obstack, alias, strlen (alias));
+    newobj->alias = obstack_copy0 (obstack, alias, strlen (alias));
   else
-    new->alias = alias;
+    newobj->alias = alias;
 
   if (declaration != NULL && copy_names)
-    new->declaration = obstack_copy0 (obstack,
+    newobj->declaration = obstack_copy0 (obstack,
                                      declaration, strlen (declaration));
   else
-    new->declaration = declaration;
+    newobj->declaration = declaration;
 
-  memcpy (new->excludes, VEC_address (const_char_ptr, excludes),
-         VEC_length (const_char_ptr, excludes) * sizeof (*new->excludes));
-  new->excludes[VEC_length (const_char_ptr, excludes)] = NULL;
+  memcpy (newobj->excludes, VEC_address (const_char_ptr, excludes),
+         VEC_length (const_char_ptr, excludes) * sizeof (*newobj->excludes));
+  newobj->excludes[VEC_length (const_char_ptr, excludes)] = NULL;
 
-  new->next = using_directives;
-  using_directives = new;
+  newobj->next = using_directives;
+  using_directives = newobj;
 }
 
 /* Test whether or not NAMESPACE looks like it mentions an anonymous
@@ -209,12 +209,12 @@ cp_is_in_anonymous (const char *symbol_name)
 }
 
 /* Look up NAME in DOMAIN in BLOCK's static block and in global blocks.
-   If ANONYMOUS_NAMESPACE is nonzero, the symbol in question is located
+   If IS_IN_ANONYMOUS is nonzero, the symbol in question is located
    within an anonymous namespace.  */
 
 static struct symbol *
 cp_basic_lookup_symbol (const char *name, const struct block *block,
-                       const domain_enum domain, int anonymous_namespace)
+                       const domain_enum domain, int is_in_anonymous)
 {
   struct symbol *sym;
 
@@ -222,7 +222,7 @@ cp_basic_lookup_symbol (const char *name, const struct block *block,
   if (sym != NULL)
     return sym;
 
-  if (anonymous_namespace)
+  if (is_in_anonymous)
     {
       /* Symbols defined in anonymous namespaces have external linkage
         but should be treated as local to a single file nonetheless.
@@ -242,12 +242,18 @@ cp_basic_lookup_symbol (const char *name, const struct block *block,
 }
 
 /* Search bare symbol NAME in DOMAIN in BLOCK.
-   NAME is guaranteed to not have any scope (no "::").
+   NAME is guaranteed to not have any scope (no "::") in its name, though
+   if for example NAME is a template spec then "::" may appear in the
+   argument list.
+   If LANGDEF is non-NULL then try to lookup NAME as a primitive type in
+   that language.  Normally we wouldn't need LANGDEF but fortran also uses
+   this code.
    If SEARCH is non-zero then see if we can determine "this" from BLOCK, and
    if so then also search for NAME in that class.  */
 
 static struct symbol *
-cp_lookup_bare_symbol (const char *name, const struct block *block,
+cp_lookup_bare_symbol (const struct language_defn *langdef,
+                      const char *name, const struct block *block,
                       const domain_enum domain, int search)
 {
   struct symbol *sym;
@@ -262,27 +268,46 @@ cp_lookup_bare_symbol (const char *name, const struct block *block,
   if (sym != NULL)
     return sym;
 
+  /* If we didn't find a definition for a builtin type in the static block,
+     search for it now.  This is actually the right thing to do and can be
+     a massive performance win.  E.g., when debugging a program with lots of
+     shared libraries we could search all of them only to find out the
+     builtin type isn't defined in any of them.  This is common for types
+     like "void".  */
+  if (langdef != NULL && domain == VAR_DOMAIN)
+    {
+      struct gdbarch *gdbarch;
+
+      if (block == NULL)
+       gdbarch = target_gdbarch ();
+      else
+       gdbarch = block_gdbarch (block);
+      sym = language_lookup_primitive_type_as_symbol (langdef, gdbarch, name);
+      if (sym != NULL)
+       return sym;
+    }
+
   sym = lookup_global_symbol (name, block, domain);
   if (sym != NULL)
     return sym;
 
   if (search)
     {
-      struct symbol *this;
+      struct symbol *lang_this;
       struct type *type;
 
-      this = lookup_language_this (language_def (language_cplus), block);
-      if (this == NULL)
+      lang_this = lookup_language_this (language_def (language_cplus), block);
+      if (lang_this == NULL)
        return NULL;
 
-      type = check_typedef (TYPE_TARGET_TYPE (SYMBOL_TYPE (this)));
+      type = check_typedef (TYPE_TARGET_TYPE (SYMBOL_TYPE (lang_this)));
       /* If TYPE_NAME is NULL, abandon trying to find this symbol.
         This can happen for lambda functions compiled with clang++,
         which outputs no name for the container class.  */
       if (TYPE_NAME (type) == NULL)
        return NULL;
 
-      /* Look for a symbol named NESTED in this class.  */
+      /* Look for symbol NAME in this class.  */
       sym = cp_lookup_nested_symbol (type, name, block);
     }
 
@@ -292,7 +317,7 @@ cp_lookup_bare_symbol (const char *name, const struct block *block,
 /* Search NAME in DOMAIN in all static blocks, and then in all baseclasses.
    BLOCK specifies the context in which to perform the search.
    NAME is guaranteed to have scope (contain "::") and PREFIX_LEN specifies
-   then length the entire scope of NAME (up to, but not including, the last
+   the length of the entire scope of NAME (up to, but not including, the last
    "::".
 
    Note: At least in the case of Fortran, which also uses this code, there
@@ -302,7 +327,8 @@ static struct symbol *
 cp_search_static_and_baseclasses (const char *name,
                                  const struct block *block,
                                  const domain_enum domain,
-                                 unsigned int prefix_len)
+                                 unsigned int prefix_len,
+                                 int is_in_anonymous)
 {
   struct symbol *sym;
   char *klass, *nested;
@@ -329,8 +355,11 @@ cp_search_static_and_baseclasses (const char *name,
   make_cleanup (xfree, nested);
 
   /* Lookup a class named KLASS.  If none is found, there is nothing
-     more that can be done.  */
-  klass_sym = lookup_global_symbol (klass, block, domain);
+     more that can be done.  KLASS could be a namespace, so always look
+     in VAR_DOMAIN.  This works for classes too because of
+     symbol_matches_domain (which should be replaced with something else,
+     but it's what we have today).  */
+  klass_sym = lookup_global_symbol (klass, block, VAR_DOMAIN);
   if (klass_sym == NULL)
     {
       do_cleanups (cleanup);
@@ -341,7 +370,8 @@ cp_search_static_and_baseclasses (const char *name,
   /* Look for a symbol named NESTED in this class.
      The caller is assumed to have already have done a basic lookup of NAME.
      So we pass zero for BASIC_LOOKUP to cp_lookup_nested_symbol_1 here.  */
-  sym = cp_lookup_nested_symbol_1 (klass_type, nested, name, block, 0);
+  sym = cp_lookup_nested_symbol_1 (klass_type, nested, name, block, 0,
+                                  is_in_anonymous);
 
   do_cleanups (cleanup);
   return sym;
@@ -357,7 +387,7 @@ cp_search_static_and_baseclasses (const char *name,
    "this" if we can compute it.  */
 
 static struct symbol *
-cp_lookup_symbol_in_namespace (const char *namespace, const char *name,
+cp_lookup_symbol_in_namespace (const char *the_namespace, const char *name,
                               const struct block *block,
                               const domain_enum domain, int search)
 {
@@ -366,11 +396,11 @@ cp_lookup_symbol_in_namespace (const char *namespace, const char *name,
   unsigned int prefix_len;
   struct symbol *sym;
 
-  if (namespace[0] != '\0')
+  if (the_namespace[0] != '\0')
     {
-      concatenated_name = alloca (strlen (namespace) + 2
+      concatenated_name = alloca (strlen (the_namespace) + 2
                                  + strlen (name) + 1);
-      strcpy (concatenated_name, namespace);
+      strcpy (concatenated_name, the_namespace);
       strcat (concatenated_name, "::");
       strcat (concatenated_name, name);
       name = concatenated_name;
@@ -378,26 +408,27 @@ cp_lookup_symbol_in_namespace (const char *namespace, const char *name,
 
   prefix_len = cp_entire_prefix_len (name);
   if (prefix_len == 0)
-    return cp_lookup_bare_symbol (name, block, domain, search);
+    return cp_lookup_bare_symbol (NULL, name, block, domain, search);
 
   /* This would be simpler if we just called cp_lookup_nested_symbol
      at this point.  But that would require first looking up the containing
      class/namespace.  Since we're only searching static and global blocks
      there's often no need to first do that lookup.  */
 
-  is_in_anonymous = namespace[0] != '\0' && cp_is_in_anonymous (namespace);
+  is_in_anonymous
+    = the_namespace[0] != '\0' && cp_is_in_anonymous (the_namespace);
   sym = cp_basic_lookup_symbol (name, block, domain, is_in_anonymous);
   if (sym != NULL)
     return sym;
 
   if (search)
-    sym = cp_search_static_and_baseclasses (name, block, domain, prefix_len);
+    sym = cp_search_static_and_baseclasses (name, block, domain, prefix_len,
+                                           is_in_anonymous);
 
   return sym;
 }
 
-/* Used for cleanups to reset the "searched" flag incase
-   of an error.  */
+/* Used for cleanups to reset the "searched" flag in case of an error.  */
 
 static void
 reset_directive_searched (void *data)
@@ -469,8 +500,7 @@ cp_lookup_symbol_via_imports (const char *scope,
 
       len = strlen (current->import_dest);
       directive_match = (search_parents
-                         ? (strncmp (scope, current->import_dest,
-                                     strlen (current->import_dest)) == 0
+                         ? (startswith (scope, current->import_dest)
                             && (len == 0
                                 || scope[len] == ':'
                                || scope[len] == '\0'))
@@ -552,8 +582,7 @@ cp_lookup_symbol_via_imports (const char *scope,
   return NULL;
 }
 
-/* Helper function that searches an array of symbols for one named
-   NAME.  */
+/* Helper function that searches an array of symbols for one named NAME.  */
 
 static struct symbol *
 search_symbol_list (const char *name, int num,
@@ -624,8 +653,7 @@ cp_lookup_symbol_imports_or_template (const char *scope,
          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
-           = get_objfile_arch (SYMBOL_OBJFILE (function));
+         struct gdbarch *arch = symbol_arch (function);
          const struct block *parent = BLOCK_SUPERBLOCK (block);
 
          while (1)
@@ -678,12 +706,35 @@ cp_lookup_symbol_imports_or_template (const char *scope,
   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 symbol *
+cp_lookup_symbol_via_all_imports (const char *scope, const char *name,
+                                 const struct block *block,
+                                 const domain_enum domain)
+{
+  struct symbol *sym;
+
+  while (block != NULL)
+    {
+      sym = cp_lookup_symbol_via_imports (scope, name, block, domain, 0, 0, 1);
+      if (sym)
+       return sym;
+
+      block = BLOCK_SUPERBLOCK (block);
+    }
+
+  return NULL;
+}
+
 /* 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*
+struct symbol *
 cp_lookup_symbol_namespace (const char *scope,
                             const char *name,
                             const struct block *block,
@@ -700,46 +751,19 @@ cp_lookup_symbol_namespace (const char *scope,
     }
 
   /* First, try to find the symbol in the given namespace.  */
-  sym = cp_lookup_symbol_in_namespace (scope, name,
-                                      block, domain, 1);
-  if (sym != NULL)
-    {
-      if (symbol_lookup_debug)
-       {
-         fprintf_unfiltered (gdb_stdlog,
-                             "cp_lookup_symbol_namespace (...) = %s\n",
-                             host_address_to_string (sym));
-       }
-      return sym;
-    }
+  sym = cp_lookup_symbol_in_namespace (scope, name, block, domain, 1);
 
-  /* Search for name in namespaces imported to this and parent
-     blocks.  */
-  while (block != NULL)
-    {
-      sym = cp_lookup_symbol_via_imports (scope, name, block,
-                                         domain, 0, 0, 1);
-
-      if (sym)
-       {
-         if (symbol_lookup_debug)
-           {
-             fprintf_unfiltered (gdb_stdlog,
-                                 "cp_lookup_symbol_namespace (...) = %s\n",
-                                 host_address_to_string (sym));
-           }
-         return sym;
-       }
-
-      block = BLOCK_SUPERBLOCK (block);
-    }
+  /* Search for name in namespaces imported to this and parent blocks.  */
+  if (sym == NULL)
+    sym = cp_lookup_symbol_via_all_imports (scope, name, block, domain);
 
   if (symbol_lookup_debug)
     {
       fprintf_unfiltered (gdb_stdlog,
-                         "cp_lookup_symbol_namespace (...) = NULL\n");
+                         "cp_lookup_symbol_namespace (...) = %s\n",
+                         sym != NULL ? host_address_to_string (sym) : "NULL");
     }
-  return NULL;
+  return sym;
 }
 
 /* Lookup NAME at namespace scope (or, in C terms, in static and
@@ -758,13 +782,14 @@ cp_lookup_symbol_namespace (const char *scope,
    "x".  */
 
 static struct symbol *
-lookup_namespace_scope (const char *name,
+lookup_namespace_scope (const struct language_defn *langdef,
+                       const char *name,
                        const struct block *block,
                        const domain_enum domain,
                        const char *scope,
                        int scope_len)
 {
-  char *namespace;
+  char *the_namespace;
 
   if (scope[scope_len] != '\0')
     {
@@ -780,19 +805,30 @@ lookup_namespace_scope (const char *name,
          new_scope_len += 2;
        }
       new_scope_len += cp_find_first_component (scope + new_scope_len);
-      sym = lookup_namespace_scope (name, block, domain,
+      sym = lookup_namespace_scope (langdef, name, block, domain,
                                    scope, new_scope_len);
       if (sym != NULL)
        return sym;
     }
 
   /* Okay, we didn't find a match in our children, so look for the
-     name in the current namespace.  */
-
-  namespace = alloca (scope_len + 1);
-  strncpy (namespace, scope, scope_len);
-  namespace[scope_len] = '\0';
-  return cp_lookup_symbol_in_namespace (namespace, name,
+     name in the current namespace.
+
+     If we there is no scope and we know we have a bare symbol, then short
+     circuit everything and call cp_lookup_bare_symbol directly.
+     This isn't an optimization, rather it allows us to pass LANGDEF which
+     is needed for primitive type lookup.  The test doesn't have to be
+     perfect: if NAME is a bare symbol that our test doesn't catch (e.g., a
+     template symbol with "::" in the argument list) then
+     cp_lookup_symbol_in_namespace will catch it.  */
+
+  if (scope_len == 0 && strchr (name, ':') == NULL)
+    return cp_lookup_bare_symbol (langdef, name, block, domain, 1);
+
+  the_namespace = alloca (scope_len + 1);
+  strncpy (the_namespace, scope, scope_len);
+  the_namespace[scope_len] = '\0';
+  return cp_lookup_symbol_in_namespace (the_namespace, name,
                                        block, domain, 1);
 }
 
@@ -803,7 +839,8 @@ lookup_namespace_scope (const char *name,
    DOMAIN says what kind of symbols we're looking for.  */
 
 struct symbol *
-cp_lookup_symbol_nonlocal (const char *name,
+cp_lookup_symbol_nonlocal (const struct language_defn *langdef,
+                          const char *name,
                           const struct block *block,
                           const domain_enum domain)
 {
@@ -819,19 +856,14 @@ cp_lookup_symbol_nonlocal (const char *name,
                          domain_name (domain));
     }
 
-  sym = lookup_namespace_scope (name, block, domain, scope, 0);
-  if (sym != NULL)
-    {
-      if (symbol_lookup_debug)
-       {
-         fprintf_unfiltered (gdb_stdlog,
-                             "cp_lookup_symbol_nonlocal (...) = %s\n",
-                             host_address_to_string (sym));
-       }
-      return sym;
-    }
+  /* First, try to find the symbol in the given namespace, and all
+     containing namespaces.  */
+  sym = lookup_namespace_scope (langdef, name, block, domain, scope, 0);
+
+  /* Search for name in namespaces imported to this and parent blocks.  */
+  if (sym == NULL)
+    sym = cp_lookup_symbol_via_all_imports (scope, name, block, domain);
 
-  sym = cp_lookup_symbol_namespace (scope, name, block, domain);
   if (symbol_lookup_debug)
     {
       fprintf_unfiltered (gdb_stdlog,
@@ -874,7 +906,7 @@ cp_find_type_baseclass_by_name (struct type *parent_type, const char *name)
 
 static struct symbol *
 find_symbol_in_baseclass (struct type *parent_type, const char *name,
-                          const struct block *block)
+                         const struct block *block, int is_in_anonymous)
 {
   int i;
   struct symbol *sym;
@@ -899,7 +931,7 @@ find_symbol_in_baseclass (struct type *parent_type, const char *name,
       xsnprintf (concatenated_name, len, "%s::%s", base_name, name);
 
       sym = cp_lookup_nested_symbol_1 (base_type, name, concatenated_name,
-                                      block, 1);
+                                      block, 1, is_in_anonymous);
       if (sym != NULL)
        break;
     }
@@ -910,21 +942,23 @@ find_symbol_in_baseclass (struct type *parent_type, const char *name,
 
 /* Helper function to look up NESTED_NAME in CONTAINER_TYPE within the
    context of BLOCK.
+   NESTED_NAME may have scope ("::").
    CONTAINER_TYPE needn't have been "check_typedef'd" yet.
    CONCATENATED_NAME is the fully scoped spelling of NESTED_NAME, it is
    passed as an argument so that callers can control how space for it is
    allocated.
    If BASIC_LOOKUP is non-zero then perform a basic lookup of
-   CONCATENATED_NAME.  See cp_basic_lookup_symbol for details.  */
+   CONCATENATED_NAME.  See cp_basic_lookup_symbol for details.
+   If IS_IN_ANONYMOUS is non-zero then CONCATENATED_NAME is in an anonymous
+   namespace.  */
 
 static struct symbol *
 cp_lookup_nested_symbol_1 (struct type *container_type,
                           const char *nested_name,
                           const char *concatenated_name,
                           const struct block *block,
-                          int basic_lookup)
+                          int basic_lookup, int is_in_anonymous)
 {
-  int is_in_anonymous = cp_is_in_anonymous (concatenated_name);
   struct symbol *sym;
 
   /* NOTE: carlton/2003-11-10: We don't treat C++ class members
@@ -954,16 +988,22 @@ cp_lookup_nested_symbol_1 (struct type *container_type,
 
   /* Nope.  We now have to search all static blocks in all objfiles,
      even if block != NULL, because there's no guarantees as to which
-     symtab the symbol we want is in.  */
-  sym = lookup_static_symbol (concatenated_name, VAR_DOMAIN);
-  if (sym != NULL)
-    return sym;
+     symtab the symbol we want is in.  Except for symbols defined in
+     anonymous namespaces should be treated as local to a single file,
+     which we just searched.  */
+  if (!is_in_anonymous)
+    {
+      sym = lookup_static_symbol (concatenated_name, VAR_DOMAIN);
+      if (sym != NULL)
+       return sym;
+    }
 
   /* If this is a class with baseclasses, search them next.  */
   CHECK_TYPEDEF (container_type);
   if (TYPE_N_BASECLASSES (container_type) > 0)
     {
-      sym = find_symbol_in_baseclass (container_type, nested_name, block);
+      sym = find_symbol_in_baseclass (container_type, nested_name, block,
+                                     is_in_anonymous);
       if (sym != NULL)
        return sym;
     }
@@ -1011,14 +1051,17 @@ cp_lookup_nested_symbol (struct type *parent_type,
        const char *parent_name = type_name_no_tag_or_error (saved_parent_type);
        struct symbol *sym;
        char *concatenated_name;
+       int is_in_anonymous;
 
        size = strlen (parent_name) + 2 + strlen (nested_name) + 1;
        concatenated_name = alloca (size);
        xsnprintf (concatenated_name, size, "%s::%s",
                   parent_name, nested_name);
+       is_in_anonymous = cp_is_in_anonymous (concatenated_name);
 
        sym = cp_lookup_nested_symbol_1 (parent_type, nested_name,
-                                        concatenated_name, block, 1);
+                                        concatenated_name, block, 1,
+                                        is_in_anonymous);
 
        if (symbol_lookup_debug)
          {
This page took 0.040257 seconds and 4 git commands to generate.