* dwarf2read.c (struct dwarf2_cu): Improve comments for members
[deliverable/binutils-gdb.git] / gdb / cp-namespace.c
index 030cfb9a4f0ff62e654df0a7ea1eaeb7cabac26d..74ccd456e61e19a289544136fc1e5f506e486f3b 100644 (file)
@@ -1,6 +1,5 @@
 /* Helper routines for C++ support in GDB.
-   Copyright (C) 2003, 2004, 2007, 2008, 2009, 2010, 2011
-   Free Software Foundation, Inc.
+   Copyright (C) 2003-2014 Free Software Foundation, Inc.
 
    Contributed by David Carlton and by Kealia, Inc.
 
@@ -43,7 +42,8 @@ static struct symbol *lookup_namespace_scope (const char *name,
 static struct symbol *lookup_symbol_file (const char *name,
                                          const struct block *block,
                                          const domain_enum domain,
-                                         int anonymous_namespace);
+                                         int anonymous_namespace,
+                                         int search);
 
 static struct type *cp_lookup_transparent_type_loop (const char *name,
                                                     const char *scope,
@@ -52,12 +52,9 @@ static struct type *cp_lookup_transparent_type_loop (const char *name,
 /* Check to see if SYMBOL refers to an object contained within an
    anonymous namespace; if so, add an appropriate using directive.  */
 
-/* Optimize away strlen ("(anonymous namespace)").  */
-
-#define ANONYMOUS_NAMESPACE_LEN 21
-
 void
-cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
+cp_scan_for_anonymous_namespaces (const struct symbol *const symbol,
+                                 struct objfile *const objfile)
 {
   if (SYMBOL_DEMANGLED_NAME (symbol) != NULL)
     {
@@ -76,10 +73,11 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
 
       while (name[next_component] == ':')
        {
-         if ((next_component - previous_component) == ANONYMOUS_NAMESPACE_LEN
+         if (((next_component - previous_component)
+              == CP_ANONYMOUS_NAMESPACE_LEN)
              && strncmp (name + previous_component,
-                         "(anonymous namespace)",
-                         ANONYMOUS_NAMESPACE_LEN) == 0)
+                         CP_ANONYMOUS_NAMESPACE_STR,
+                         CP_ANONYMOUS_NAMESPACE_LEN) == 0)
            {
              int dest_len = (previous_component == 0
                              ? 0 : previous_component - 2);
@@ -98,8 +96,8 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
                 anonymous namespace.  So add symbols in it to the
                 namespace given by the previous component if there is
                 one, or to the global namespace if there isn't.  */
-             cp_add_using_directive (dest, src, NULL, NULL,
-                                     &SYMBOL_SYMTAB (symbol)->objfile->objfile_obstack);
+             cp_add_using_directive (dest, src, NULL, NULL, NULL, 1,
+                                     &objfile->objfile_obstack);
            }
          /* The "+ 2" is for the "::".  */
          previous_component = next_component + 2;
@@ -119,14 +117,19 @@ cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
    in the current scope.  If ALIAS is NULL then the namespace is known
    by its original name.  DECLARATION is the name if the imported
    varable if this is a declaration import (Eg. using A::x), otherwise
-   it is NULL.  The arguments are copied into newly allocated memory
-   so they can be temporaries.  */
+   it is NULL.  EXCLUDES is a list of names not to import from an
+   imported module or NULL.  If COPY_NAMES is non-zero, then the
+   arguments are copied into newly allocated memory so they can be
+   temporaries.  For EXCLUDES the VEC pointers are copied but the
+   pointed to characters are not copied.  */
 
 void
 cp_add_using_directive (const char *dest,
                        const char *src,
                        const char *alias,
                        const char *declaration,
+                       VEC (const_char_ptr) *excludes,
+                       int copy_names,
                         struct obstack *obstack)
 {
   struct using_direct *current;
@@ -136,69 +139,70 @@ cp_add_using_directive (const char *dest,
 
   for (current = using_directives; current != NULL; current = current->next)
     {
-      if (strcmp (current->import_src, src) == 0
-          && strcmp (current->import_dest, dest) == 0
-          && ((alias == NULL && current->alias == NULL)
-              || (alias != NULL && current->alias != NULL
-                 && strcmp (alias, current->alias) == 0))
-         && ((declaration == NULL && current->declaration == NULL)
-             || (declaration != NULL && current->declaration != NULL
-                 && strcmp (declaration, current->declaration) == 0)))
-       return;
+      int ix;
+      const char *param;
+
+      if (strcmp (current->import_src, src) != 0)
+       continue;
+      if (strcmp (current->import_dest, dest) != 0)
+       continue;
+      if ((alias == NULL && current->alias != NULL)
+         || (alias != NULL && current->alias == NULL)
+         || (alias != NULL && current->alias != NULL
+             && strcmp (alias, current->alias) != 0))
+       continue;
+      if ((declaration == NULL && current->declaration != NULL)
+         || (declaration != NULL && current->declaration == NULL)
+         || (declaration != NULL && current->declaration != NULL
+             && strcmp (declaration, current->declaration) != 0))
+       continue;
+
+      /* Compare the contents of EXCLUDES.  */
+      for (ix = 0; VEC_iterate (const_char_ptr, excludes, ix, param); ix++)
+       if (current->excludes[ix] == NULL
+           || strcmp (param, current->excludes[ix]) != 0)
+         break;
+      if (ix < VEC_length (const_char_ptr, excludes)
+         || current->excludes[ix] != NULL)
+       continue;
+
+      /* Parameters exactly match CURRENT.  */
+      return;
     }
 
-  new = OBSTACK_ZALLOC (obstack, struct using_direct);
-
-  new->import_src = obsavestring (src, strlen (src), obstack);
-  new->import_dest = obsavestring (dest, strlen (dest), obstack);
-
-  if (alias != NULL)
-    new->alias = obsavestring (alias, strlen (alias), obstack);
-
-  if (declaration != NULL)
-    new->declaration = obsavestring (declaration, strlen (declaration),
-                                     obstack);
-
-  new->next = using_directives;
-  using_directives = new;
-}
-
-/* Record the namespace that the function defined by SYMBOL was
-   defined in, if necessary.  BLOCK is the associated block; use
-   OBSTACK for allocation.  */
+  new = obstack_alloc (obstack, (sizeof (*new)
+                                + (VEC_length (const_char_ptr, excludes)
+                                   * sizeof (*new->excludes))));
+  memset (new, 0, sizeof (*new));
 
-void
-cp_set_block_scope (const struct symbol *symbol,
-                   struct block *block,
-                   struct obstack *obstack,
-                   const char *processing_current_prefix,
-                   int processing_has_namespace_info)
-{
-  if (processing_has_namespace_info)
+  if (copy_names)
     {
-      block_set_scope
-       (block, obsavestring (processing_current_prefix,
-                             strlen (processing_current_prefix),
-                             obstack),
-        obstack);
+      new->import_src = obstack_copy0 (obstack, src, strlen (src));
+      new->import_dest = obstack_copy0 (obstack, dest, strlen (dest));
     }
-  else if (SYMBOL_DEMANGLED_NAME (symbol) != NULL)
+  else
     {
-      /* Try to figure out the appropriate namespace from the
-        demangled name.  */
+      new->import_src = src;
+      new->import_dest = dest;
+    }
 
-      /* FIXME: carlton/2003-04-15: If the function in question is
-        a method of a class, the name will actually include the
-        name of the class as well.  This should be harmless, but
-        is a little unfortunate.  */
+  if (alias != NULL && copy_names)
+    new->alias = obstack_copy0 (obstack, alias, strlen (alias));
+  else
+    new->alias = alias;
 
-      const char *name = SYMBOL_DEMANGLED_NAME (symbol);
-      unsigned int prefix_len = cp_entire_prefix_len (name);
+  if (declaration != NULL && copy_names)
+    new->declaration = obstack_copy0 (obstack,
+                                     declaration, strlen (declaration));
+  else
+    new->declaration = declaration;
 
-      block_set_scope (block,
-                      obsavestring (name, prefix_len, obstack),
-                      obstack);
-    }
+  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;
+
+  new->next = using_directives;
+  using_directives = new;
 }
 
 /* Test whether or not NAMESPACE looks like it mentions an anonymous
@@ -207,7 +211,7 @@ cp_set_block_scope (const struct symbol *symbol,
 int
 cp_is_anonymous (const char *namespace)
 {
-  return (strstr (namespace, "(anonymous namespace)")
+  return (strstr (namespace, CP_ANONYMOUS_NAMESPACE_STR)
          != NULL);
 }
 
@@ -237,17 +241,18 @@ cp_lookup_symbol_nonlocal (const char *name,
 }
 
 /* Look up NAME in the C++ namespace NAMESPACE.  Other arguments are
-   as in cp_lookup_symbol_nonlocal.  */
+   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)
+                               const domain_enum domain, int search)
 {
   if (namespace[0] == '\0')
     {
-      return lookup_symbol_file (name, block, domain, 0);
+      return lookup_symbol_file (name, block, domain, 0, search);
     }
   else
     {
@@ -258,7 +263,7 @@ cp_lookup_symbol_in_namespace (const char *namespace,
       strcat (concatenated_name, "::");
       strcat (concatenated_name, name);
       return lookup_symbol_file (concatenated_name, block, domain,
-                                cp_is_anonymous (namespace));
+                                cp_is_anonymous (namespace), search);
     }
 }
 
@@ -314,7 +319,7 @@ cp_lookup_symbol_imports (const char *scope,
   /* First, try to find the symbol in the given namespace.  */
   if (!declaration_only)
     sym = cp_lookup_symbol_in_namespace (scope, name,
-                                        block, domain);
+                                        block, domain, 1);
   
   if (sym != NULL)
     return sym;
@@ -327,6 +332,8 @@ cp_lookup_symbol_imports (const char *scope,
        current != NULL;
        current = current->next)
     {
+      const char **excludep;
+
       len = strlen (current->import_dest);
       directive_match = (search_parents
                          ? (strncmp (scope, current->import_dest,
@@ -340,62 +347,72 @@ cp_lookup_symbol_imports (const char *scope,
          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);
-
-       /* 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;
-          }
-
-       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);
-         }
-       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);
+         /* 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;
+             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;
        }
     }
 
@@ -434,10 +451,6 @@ cp_lookup_symbol_imports_or_template (const char *scope,
 
   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))
        {
@@ -460,7 +473,8 @@ 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 = SYMBOL_SYMTAB (function)->objfile->gdbarch;
+         struct gdbarch *arch
+           = get_objfile_arch (SYMBOL_SYMTAB (function)->objfile);
          const struct block *parent = BLOCK_SUPERBLOCK (block);
 
          while (1)
@@ -486,7 +500,10 @@ cp_lookup_symbol_imports_or_template (const char *scope,
                                      TYPE_N_TEMPLATE_ARGUMENTS (context),
                                      TYPE_TEMPLATE_ARGUMENTS (context));
              if (result != NULL)
-               return result;
+               {
+                 do_cleanups (cleanups);
+                 return result;
+               }
            }
 
          do_cleanups (cleanups);
@@ -511,7 +528,7 @@ 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);
+                                      block, domain, 1);
   if (sym != NULL)
     return sym;
 
@@ -582,19 +599,20 @@ lookup_namespace_scope (const char *name,
   strncpy (namespace, scope, scope_len);
   namespace[scope_len] = '\0';
   return cp_lookup_symbol_in_namespace (namespace, name,
-                                       block, domain);
+                                       block, domain, 1);
 }
 
 /* Look up NAME in BLOCK's static block and in global blocks.  If
    ANONYMOUS_NAMESPACE is nonzero, the symbol in question is located
-   within an anonymous namespace.  Other arguments are as in
+   within an anonymous namespace.  If SEARCH is non-zero, search through
+   base classes for a matching symbol.  Other arguments are as in
    cp_lookup_symbol_nonlocal.  */
 
 static struct symbol *
 lookup_symbol_file (const char *name,
                    const struct block *block,
                    const domain_enum domain,
-                   int anonymous_namespace)
+                   int anonymous_namespace, int search)
 {
   struct symbol *sym = NULL;
 
@@ -618,23 +636,186 @@ lookup_symbol_file (const char *name,
       sym = lookup_symbol_global (name, block, domain);
     }
 
+  if (sym != NULL)
+    return sym;
+
+  if (search)
+    {
+      char *klass, *nested;
+      unsigned int prefix_len;
+      struct cleanup *cleanup;
+      struct symbol *klass_sym;
+
+      /* A simple lookup failed.  Check if the symbol was defined in
+        a base class.  */
+
+      cleanup = make_cleanup (null_cleanup, NULL);
+
+      /* Find the name of the class and the name of the method,
+        variable, etc.  */
+      prefix_len = cp_entire_prefix_len (name);
+
+      /* If no prefix was found, search "this".  */
+      if (prefix_len == 0)
+       {
+         struct type *type;
+         struct symbol *this;
+
+         this = lookup_language_this (language_def (language_cplus), block);
+         if (this == NULL)
+           {
+             do_cleanups (cleanup);
+             return NULL;
+           }
+
+         type = check_typedef (TYPE_TARGET_TYPE (SYMBOL_TYPE (this)));
+         klass = xstrdup (TYPE_NAME (type));
+         nested = xstrdup (name);
+       }
+      else
+       {
+         /* The class name is everything up to and including PREFIX_LEN.  */
+         klass = savestring (name, prefix_len);
+
+         /* The rest of the name is everything else past the initial scope
+            operator.  */
+         nested = xstrdup (name + prefix_len + 2);
+       }
+
+      /* Add cleanups to free memory for these strings.  */
+      make_cleanup (xfree, klass);
+      make_cleanup (xfree, nested);
+
+      /* Lookup a class named KLASS.  If none is found, there is nothing
+        more that can be done.  */
+      klass_sym = lookup_symbol_global (klass, block, domain);
+      if (klass_sym == NULL)
+       {
+         do_cleanups (cleanup);
+         return NULL;
+       }
+
+      /* Look for a symbol named NESTED in this class.  */
+      sym = cp_lookup_nested_symbol (SYMBOL_TYPE (klass_sym), nested, block);
+      do_cleanups (cleanup);
+    }
+
+  return sym;
+}
+
+/* Search through the base classes of PARENT_TYPE for a base class
+   named NAME and return its type.  If not found, return NULL.  */
+
+struct type *
+find_type_baseclass_by_name (struct type *parent_type, const char *name)
+{
+  int i;
+
+  CHECK_TYPEDEF (parent_type);
+  for (i = 0; i < TYPE_N_BASECLASSES (parent_type); ++i)
+    {
+      struct type *type = check_typedef (TYPE_BASECLASS (parent_type, i));
+      const char *base_name = TYPE_BASECLASS_NAME (parent_type, i);
+
+      if (base_name == NULL)
+       continue;
+
+      if (streq (base_name, name))
+       return type;
+
+      type = find_type_baseclass_by_name (type, name);
+      if (type != NULL)
+       return type;
+    }
+
+  return NULL;
+}
+
+/* Search through the base classes of PARENT_TYPE for a symbol named
+   NAME in block BLOCK.  */
+
+static struct symbol *
+find_symbol_in_baseclass (struct type *parent_type, const char *name,
+                          const struct block *block)
+{
+  int i;
+  struct symbol *sym;
+  struct cleanup *cleanup;
+  char *concatenated_name;
+
+  sym = NULL;
+  concatenated_name = NULL;
+  cleanup = make_cleanup (free_current_contents, &concatenated_name);
+  for (i = 0; i < TYPE_N_BASECLASSES (parent_type); ++i)
+    {
+      size_t len;
+      struct type *base_type = TYPE_BASECLASS (parent_type, i);
+      const char *base_name = TYPE_BASECLASS_NAME (parent_type, i);
+
+      if (base_name == NULL)
+       continue;
+
+      /* Search this particular base class.  */
+      sym = cp_lookup_symbol_in_namespace (base_name, name, block,
+                                          VAR_DOMAIN, 0);
+      if (sym != NULL)
+       break;
+
+      /* Now search all static file-level symbols.  We have to do this for
+        things like typedefs in the class.  First search in this symtab,
+        what we want is possibly there.  */
+      len = strlen (base_name) + 2 + strlen (name) + 1;
+      concatenated_name = xrealloc (concatenated_name, len);
+      xsnprintf (concatenated_name, len, "%s::%s", base_name, name);
+      sym = lookup_symbol_static (concatenated_name, block, VAR_DOMAIN);
+      if (sym != NULL)
+       break;
+
+      /* 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_aux (concatenated_name, VAR_DOMAIN);
+      if (sym != NULL)
+       break;
+
+      /* If this class has base classes, search them next.  */
+      CHECK_TYPEDEF (base_type);
+      if (TYPE_N_BASECLASSES (base_type) > 0)
+       {
+         sym = find_symbol_in_baseclass (base_type, name, block);
+         if (sym != NULL)
+           break;
+       }
+    }
+
+  do_cleanups (cleanup);
   return sym;
 }
 
-/* Look up a type named NESTED_NAME that is nested inside the C++
+/* Look up a symbol named NESTED_NAME that is nested inside the C++
    class or namespace given by PARENT_TYPE, from within the context
    given by BLOCK.  Return NULL if there is no such nested type.  */
 
-struct type *
-cp_lookup_nested_type (struct type *parent_type,
-                      const char *nested_name,
-                      const struct block *block)
+struct symbol *
+cp_lookup_nested_symbol (struct type *parent_type,
+                        const char *nested_name,
+                        const struct block *block)
 {
+  /* type_name_no_tag_required provides better error reporting using the
+     original type.  */
+  struct type *saved_parent_type = parent_type;
+
+  CHECK_TYPEDEF (parent_type);
+
   switch (TYPE_CODE (parent_type))
     {
     case TYPE_CODE_STRUCT:
     case TYPE_CODE_NAMESPACE:
     case TYPE_CODE_UNION:
+    /* NOTE: Handle modules here as well, because Fortran is re-using the C++
+       specific code to lookup nested symbols in modules, by calling the
+       function pointer la_lookup_symbol_nonlocal, which ends up here.  */
+    case TYPE_CODE_MODULE:
       {
        /* NOTE: carlton/2003-11-10: We don't treat C++ class members
           of classes like, say, data or function members.  Instead,
@@ -643,35 +824,42 @@ cp_lookup_nested_type (struct type *parent_type,
           just like members of namespaces; in particular,
           lookup_symbol_namespace works when looking them up.  */
 
-       const char *parent_name = TYPE_TAG_NAME (parent_type);
+       int size;
+       const char *parent_name = type_name_no_tag_or_error (saved_parent_type);
        struct symbol *sym
          = cp_lookup_symbol_in_namespace (parent_name, nested_name,
-                                          block, VAR_DOMAIN);
+                                          block, VAR_DOMAIN, 0);
        char *concatenated_name;
 
-       if (sym != NULL && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
-         return SYMBOL_TYPE (sym);
+       if (sym != NULL)
+         return sym;
 
-       /* Now search all static file-level symbols.  Not strictly
-          correct, but more useful than an error.  We do not try to
+       /* Now search all static file-level symbols.  We have to do this
+          for things like typedefs in the class.  We do not try to
           guess any imported namespace as even the fully specified
-          namespace seach is is already not C++ compliant and more
+          namespace search 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",
+       size = strlen (parent_name) + 2 + strlen (nested_name) + 1;
+       concatenated_name = alloca (size);
+       xsnprintf (concatenated_name, size, "%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);
+       sym = lookup_static_symbol_aux (concatenated_name, VAR_DOMAIN);
+       if (sym != NULL)
+         return sym;
 
-       return NULL;
+       /* If no matching symbols were found, try searching any
+          base classes.  */
+       return find_symbol_in_baseclass (parent_type, nested_name, block);
       }
+
+    case TYPE_CODE_FUNC:
+    case TYPE_CODE_METHOD:
+      return NULL;
+
     default:
       internal_error (__FILE__, __LINE__,
-                     _("cp_lookup_nested_type called "
+                     _("cp_lookup_nested_symbol called "
                        "on a non-aggregate type."));
     }
 }
This page took 0.067717 seconds and 4 git commands to generate.