* config/pa/linux.mh (XDEPFILES): Remove.
[binutils-gdb.git] / gdb / cp-namespace.c
index fed440ebc5001271efb7f2ec6e550005dd053824..b22f0311cc7df8d514dd8ce93fabb2dd67902331 100644 (file)
@@ -1,5 +1,5 @@
 /* Helper routines for C++ support in GDB.
-   Copyright 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2007, 2008, 2009 Free Software Foundation, Inc.
 
    Contributed by David Carlton and by Kealia, Inc.
 
@@ -7,7 +7,7 @@
 
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
-   the Free Software Foundation; either version 2 of the License, or
+   the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.
 
    This program is distributed in the hope that it will be useful,
@@ -16,9 +16,7 @@
    GNU General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330,
-   Boston, MA 02111-1307, USA.  */
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "defs.h"
 #include "cp-support.h"
 #include "gdbtypes.h"
 #include "dictionary.h"
 #include "command.h"
-
-/* When set, the file that we're processing is known to have debugging
-   info for C++ namespaces.  */
-
-/* NOTE: carlton/2004-01-13: No currently released version of GCC (the
-   latest of which is 3.3.x at the time of this writing) produces this
-   debug info.  GCC 3.4 should, however.  */
-
-unsigned char processing_has_namespace_info;
-
-/* This contains our best guess as to the name of the current
-   enclosing namespace(s)/class(es), if any.  For example, if we're
-   within the method foo() in the following code:
-
-    namespace N {
-      class C {
-       void foo () {
-       }
-      };
-    }
-
-   then processing_current_prefix should be set to "N::C".  If
-   processing_has_namespace_info is false, then this variable might
-   not be reliable.  */
-
-const char *processing_current_prefix;
+#include "frame.h"
 
 /* List of using directives that are active in the current file.  */
 
@@ -74,7 +47,6 @@ static struct symbol *lookup_namespace_scope (const char *name,
                                              const char *linkage_name,
                                              const struct block *block,
                                              const domain_enum domain,
-                                             struct symtab **symtab,
                                              const char *scope,
                                              int scope_len);
 
@@ -82,9 +54,12 @@ static struct symbol *lookup_symbol_file (const char *name,
                                          const char *linkage_name,
                                          const struct block *block,
                                          const domain_enum domain,
-                                         struct symtab **symtab,
                                          int anonymous_namespace);
 
+static struct type *cp_lookup_transparent_type_loop (const char *name,
+                                                    const char *scope,
+                                                    int scope_len);
+
 static void initialize_namespace_symtab (struct objfile *objfile);
 
 static struct block *get_possible_namespace_block (struct objfile *objfile);
@@ -99,9 +74,7 @@ static int check_one_possible_namespace_symbol (const char *name,
                                                int len,
                                                struct objfile *objfile);
 
-static
-struct symbol *lookup_possible_namespace_symbol (const char *name,
-                                                struct symtab **symtab);
+static struct symbol *lookup_possible_namespace_symbol (const char *name);
 
 static void maintenance_cplus_namespace (char *args, int from_tty);
 
@@ -110,7 +83,6 @@ static void maintenance_cplus_namespace (char *args, int from_tty);
 
 void cp_initialize_namespace ()
 {
-  processing_has_namespace_info = 0;
   using_list = NULL;
 }
 
@@ -141,10 +113,9 @@ cp_finalize_namespace (struct block *static_block,
 void
 cp_scan_for_anonymous_namespaces (const struct symbol *symbol)
 {
-  if (!processing_has_namespace_info
-      && SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL)
+  if (SYMBOL_DEMANGLED_NAME (symbol) != NULL)
     {
-      const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
+      const char *name = SYMBOL_DEMANGLED_NAME (symbol);
       unsigned int previous_component;
       unsigned int next_component;
       const char *len;
@@ -218,38 +189,34 @@ cp_add_using_directive (const char *name, unsigned int outer_length,
 void
 cp_set_block_scope (const struct symbol *symbol,
                    struct block *block,
-                   struct obstack *obstack)
+                   struct obstack *obstack,
+                   const char *processing_current_prefix,
+                   int processing_has_namespace_info)
 {
-  /* Make sure that the name was originally mangled: if not, there
-     certainly isn't any namespace information to worry about!  */
-
-  if (SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL)
+  if (processing_has_namespace_info)
     {
-      if (processing_has_namespace_info)
-       {
-         block_set_scope
-           (block, obsavestring (processing_current_prefix,
-                                 strlen (processing_current_prefix),
-                                 obstack),
-            obstack);
-       }
-      else
-       {
-         /* Try to figure out the appropriate namespace from the
-            demangled name.  */
+      block_set_scope
+       (block, obsavestring (processing_current_prefix,
+                             strlen (processing_current_prefix),
+                             obstack),
+        obstack);
+    }
+  else if (SYMBOL_DEMANGLED_NAME (symbol) != NULL)
+    {
+      /* Try to figure out the appropriate namespace from the
+        demangled name.  */
 
-         /* 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.  */
+      /* 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.  */
 
-         const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
-         unsigned int prefix_len = cp_entire_prefix_len (name);
+      const char *name = SYMBOL_DEMANGLED_NAME (symbol);
+      unsigned int prefix_len = cp_entire_prefix_len (name);
 
-         block_set_scope (block,
-                          obsavestring (name, prefix_len, obstack),
-                          obstack);
-       }
+      block_set_scope (block,
+                      obsavestring (name, prefix_len, obstack),
+                      obstack);
     }
 }
 
@@ -330,11 +297,10 @@ struct symbol *
 cp_lookup_symbol_nonlocal (const char *name,
                           const char *linkage_name,
                           const struct block *block,
-                          const domain_enum domain,
-                          struct symtab **symtab)
+                          const domain_enum domain)
 {
   return lookup_namespace_scope (name, linkage_name, block, domain,
-                                symtab, block_scope (block), 0);
+                                block_scope (block), 0);
 }
 
 /* Lookup NAME at namespace scope (or, in C terms, in static and
@@ -357,7 +323,6 @@ lookup_namespace_scope (const char *name,
                        const char *linkage_name,
                        const struct block *block,
                        const domain_enum domain,
-                       struct symtab **symtab,
                        const char *scope,
                        int scope_len)
 {
@@ -378,8 +343,7 @@ lookup_namespace_scope (const char *name,
        }
       new_scope_len += cp_find_first_component (scope + new_scope_len);
       sym = lookup_namespace_scope (name, linkage_name, block,
-                                   domain, symtab,
-                                   scope, new_scope_len);
+                                   domain, scope, new_scope_len);
       if (sym != NULL)
        return sym;
     }
@@ -391,7 +355,7 @@ lookup_namespace_scope (const char *name,
   strncpy (namespace, scope, scope_len);
   namespace[scope_len] = '\0';
   return cp_lookup_symbol_namespace (namespace, name, linkage_name,
-                                    block, domain, symtab);
+                                    block, domain);
 }
 
 /* Look up NAME in the C++ namespace NAMESPACE, applying the using
@@ -403,8 +367,7 @@ cp_lookup_symbol_namespace (const char *namespace,
                            const char *name,
                            const char *linkage_name,
                            const struct block *block,
-                           const domain_enum domain,
-                           struct symtab **symtab)
+                           const domain_enum domain)
 {
   const struct using_direct *current;
   struct symbol *sym;
@@ -423,8 +386,7 @@ cp_lookup_symbol_namespace (const char *namespace,
                                            name,
                                            linkage_name,
                                            block,
-                                           domain,
-                                           symtab);
+                                           domain);
          if (sym != NULL)
            return sym;
        }
@@ -437,7 +399,7 @@ cp_lookup_symbol_namespace (const char *namespace,
   if (namespace[0] == '\0')
     {
       return lookup_symbol_file (name, linkage_name, block,
-                                domain, symtab, 0);
+                                domain, 0);
     }
   else
     {
@@ -447,7 +409,7 @@ cp_lookup_symbol_namespace (const char *namespace,
       strcat (concatenated_name, "::");
       strcat (concatenated_name, name);
       sym = lookup_symbol_file (concatenated_name, linkage_name,
-                               block, domain, symtab,
+                               block, domain, 
                                cp_is_anonymous (namespace));
       return sym;
     }
@@ -463,12 +425,11 @@ lookup_symbol_file (const char *name,
                    const char *linkage_name,
                    const struct block *block,
                    const domain_enum domain,
-                   struct symtab **symtab,
                    int anonymous_namespace)
 {
   struct symbol *sym = NULL;
 
-  sym = lookup_symbol_static (name, linkage_name, block, domain, symtab);
+  sym = lookup_symbol_static (name, linkage_name, block, domain);
   if (sym != NULL)
     return sym;
 
@@ -482,11 +443,11 @@ lookup_symbol_file (const char *name,
       
       if (global_block != NULL)
        sym = lookup_symbol_aux_block (name, linkage_name, global_block,
-                                      domain, symtab);
+                                      domain);
     }
   else
     {
-      sym = lookup_symbol_global (name, linkage_name, domain, symtab);
+      sym = lookup_symbol_global (name, linkage_name, block, domain);
     }
 
   if (sym != NULL)
@@ -504,7 +465,7 @@ lookup_symbol_file (const char *name,
 
   if (domain == VAR_DOMAIN)
     {
-      sym = lookup_possible_namespace_symbol (name, symtab);
+      sym = lookup_possible_namespace_symbol (name);
       if (sym != NULL)
        return sym;
     }
@@ -538,8 +499,7 @@ cp_lookup_nested_type (struct type *parent_type,
                                                         nested_name,
                                                         NULL,
                                                         block,
-                                                        VAR_DOMAIN,
-                                                        NULL);
+                                                        VAR_DOMAIN);
        if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF)
          return NULL;
        else
@@ -547,10 +507,78 @@ cp_lookup_nested_type (struct type *parent_type,
       }
     default:
       internal_error (__FILE__, __LINE__,
-                     "cp_lookup_nested_type called on a non-aggregate type.");
+                     _("cp_lookup_nested_type called on a non-aggregate type."));
     }
 }
 
+/* The C++-version of lookup_transparent_type.  */
+
+/* FIXME: carlton/2004-01-16: The problem that this is trying to
+   address is that, unfortunately, sometimes NAME is wrong: it may not
+   include the name of namespaces enclosing the type in question.
+   lookup_transparent_type gets called when the the type in question
+   is a declaration, and we're trying to find its definition; but, for
+   declarations, our type name deduction mechanism doesn't work.
+   There's nothing we can do to fix this in general, I think, in the
+   absence of debug information about namespaces (I've filed PR
+   gdb/1511 about this); until such debug information becomes more
+   prevalent, one heuristic which sometimes looks is to search for the
+   definition in namespaces containing the current namespace.
+
+   We should delete this functions once the appropriate debug
+   information becomes more widespread.  (GCC 3.4 will be the first
+   released version of GCC with such information.)  */
+
+struct type *
+cp_lookup_transparent_type (const char *name)
+{
+  /* First, try the honest way of looking up the definition.  */
+  struct type *t = basic_lookup_transparent_type (name);
+  const char *scope;
+
+  if (t != NULL)
+    return t;
+
+  /* If that doesn't work and we're within a namespace, look there
+     instead.  */
+  scope = block_scope (get_selected_block (0));
+
+  if (scope[0] == '\0')
+    return NULL;
+
+  return cp_lookup_transparent_type_loop (name, scope, 0);
+}
+
+/* Lookup the the type definition associated to NAME in
+   namespaces/classes containing SCOPE whose name is strictly longer
+   than LENGTH.  LENGTH must be the index of the start of a
+   component of SCOPE.  */
+
+static struct type *
+cp_lookup_transparent_type_loop (const char *name, const char *scope,
+                                int length)
+{
+  int scope_length = length + cp_find_first_component (scope + length);
+  char *full_name;
+
+  /* If the current scope is followed by "::", look in the next
+     component.  */
+  if (scope[scope_length] == ':')
+    {
+      struct type *retval
+       = cp_lookup_transparent_type_loop (name, scope, scope_length + 2);
+      if (retval != NULL)
+       return retval;
+    }
+
+  full_name = alloca (scope_length + 2 + strlen (name) + 1);
+  strncpy (full_name, scope, scope_length);
+  strncpy (full_name + scope_length, "::", 2);
+  strcpy (full_name + scope_length + 2, name);
+
+  return basic_lookup_transparent_type (full_name);
+}
+
 /* Now come functions for dealing with symbols associated to
    namespaces.  (They're used to store the namespaces themselves, not
    objects that live in the namespaces.)  These symbols come in two
@@ -582,7 +610,7 @@ initialize_namespace_symtab (struct objfile *objfile)
   namespace_symtab->free_code = free_nothing;
   namespace_symtab->dirname = NULL;
 
-  bv = obstack_alloc (&objfile->symbol_obstack,
+  bv = obstack_alloc (&objfile->objfile_obstack,
                      sizeof (struct blockvector)
                      + FIRST_LOCAL_BLOCK * sizeof (struct block *));
   BLOCKVECTOR_NBLOCKS (bv) = FIRST_LOCAL_BLOCK + 1;
@@ -590,12 +618,12 @@ initialize_namespace_symtab (struct objfile *objfile)
   
   /* Allocate empty GLOBAL_BLOCK and STATIC_BLOCK. */
 
-  bl = allocate_block (&objfile->symbol_obstack);
-  BLOCK_DICT (bl) = dict_create_linear (&objfile->symbol_obstack,
+  bl = allocate_block (&objfile->objfile_obstack);
+  BLOCK_DICT (bl) = dict_create_linear (&objfile->objfile_obstack,
                                        NULL);
   BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK) = bl;
-  bl = allocate_block (&objfile->symbol_obstack);
-  BLOCK_DICT (bl) = dict_create_linear (&objfile->symbol_obstack,
+  bl = allocate_block (&objfile->objfile_obstack);
+  BLOCK_DICT (bl) = dict_create_linear (&objfile->objfile_obstack,
                                        NULL);
   BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
 
@@ -613,7 +641,7 @@ initialize_namespace_symtab (struct objfile *objfile)
      having a symtab/block for this purpose seems like the best
      solution for now.  */
 
-  bl = allocate_block (&objfile->symbol_obstack);
+  bl = allocate_block (&objfile->objfile_obstack);
   BLOCK_DICT (bl) = dict_create_hashed_expandable ();
   BLOCKVECTOR_BLOCK (bv, FIRST_LOCAL_BLOCK) = bl;
 
@@ -710,17 +738,23 @@ check_one_possible_namespace_symbol (const char *name, int len,
                                     struct objfile *objfile)
 {
   struct block *block = get_possible_namespace_block (objfile);
-  char *name_copy = obsavestring (name, len, &objfile->symbol_obstack);
-  struct symbol *sym = lookup_block_symbol (block, name_copy, NULL,
-                                           VAR_DOMAIN);
+  char *name_copy = alloca (len + 1);
+  struct symbol *sym;
+
+  memcpy (name_copy, name, len);
+  name_copy[len] = '\0';
+  sym = lookup_block_symbol (block, name_copy, NULL, VAR_DOMAIN);
 
   if (sym == NULL)
     {
-      struct type *type = init_type (TYPE_CODE_NAMESPACE, 0, 0,
-                                    name_copy, objfile);
+      struct type *type;
+      name_copy = obsavestring (name, len, &objfile->objfile_obstack);
+
+      type = init_type (TYPE_CODE_NAMESPACE, 0, 0, name_copy, objfile);
+
       TYPE_TAG_NAME (type) = TYPE_NAME (type);
 
-      sym = obstack_alloc (&objfile->symbol_obstack, sizeof (struct symbol));
+      sym = obstack_alloc (&objfile->objfile_obstack, sizeof (struct symbol));
       memset (sym, 0, sizeof (struct symbol));
       SYMBOL_LANGUAGE (sym) = language_cplus;
       SYMBOL_SET_NAMES (sym, name_copy, len, objfile);
@@ -733,19 +767,14 @@ check_one_possible_namespace_symbol (const char *name, int len,
       return 0;
     }
   else
-    {
-      obstack_free (&objfile->symbol_obstack, name_copy);
-
-      return 1;
-    }
+    return 1;
 }
 
 /* Look for a symbol named NAME in all the possible namespace blocks.
-   If one is found, return it; if SYMTAB is non-NULL, set *SYMTAB to
-   equal the symtab where it was found.  */
+   If one is found, return it.  */
 
 static struct symbol *
-lookup_possible_namespace_symbol (const char *name, struct symtab **symtab)
+lookup_possible_namespace_symbol (const char *name)
 {
   struct objfile *objfile;
 
@@ -757,12 +786,7 @@ lookup_possible_namespace_symbol (const char *name, struct symtab **symtab)
                                 name, NULL, VAR_DOMAIN);
 
       if (sym != NULL)
-       {
-         if (symtab != NULL)
-           *symtab = objfile->cp_namespace_symtab;
-
-         return sym;
-       }
+       return sym;
     }
 
   return NULL;
@@ -774,7 +798,7 @@ static void
 maintenance_cplus_namespace (char *args, int from_tty)
 {
   struct objfile *objfile;
-  printf_unfiltered ("Possible namespaces:\n");
+  printf_unfiltered (_("Possible namespaces:\n"));
   ALL_OBJFILES (objfile)
     {
       struct dict_iterator iter;
@@ -791,6 +815,6 @@ void
 _initialize_cp_namespace (void)
 {
   add_cmd ("namespace", class_maintenance, maintenance_cplus_namespace,
-          "Print the list of possible C++ namespaces.",
+          _("Print the list of possible C++ namespaces."),
           &maint_cplus_cmd_list);
 }