]> git.ipfire.org Git - thirdparty/binutils-gdb.git/commitdiff
2002-11-22 David Carlton <carlton@math.stanford.edu>
authorDavid Carlton <carlton@bactrian.org>
Fri, 22 Nov 2002 17:15:56 +0000 (17:15 +0000)
committerDavid Carlton <carlton@bactrian.org>
Fri, 22 Nov 2002 17:15:56 +0000 (17:15 +0000)
* symtab.h: Add opaque declarations for struct namespace_info and
struct obstack.
(struct block): The language_specific stuff is now a struct
namespace_info rather than a struct using_direct_node.
(BLOCK_NAMESPACE): New macro.
Delete macro BLOCK_USING.
Add declarations for block_using, block_all_usings,
block_set_using, block_scope, block_set_scope.
* symtab.c: #include "gdb_assert.h"
(lookup_symbol_aux): Move minsym stuff inside
lookup_symbol_aux_nonlocal, and always do global search via
lookup_symbol_aux_using.
(lookup_symbol_aux_nonlocal): Do minsym search.
(lookup_symbol_aux_using): Calculate usings via block_all_usings;
handle namespace scope.
(lookup_symbol_aux_using_loop): New function, not to be confused
with the previous function of the same name.  (Sorry about that.)
(lookup_symbol_namespace): Renamed from
lookup_symbol_aux_using_loop.
(lookup_symbol_aux_minsyms): Add block_index argument, delete
is_a_field_of_this argument, and only check either global or
static symbols rather than both of them.
(block_using): New function.
(block_all_usings): New function.
(block_set_using): New function.
(block_scope): New function.
(block_set_scope): New function.
(block_initialize_namespace): New function.
* jv-lang.c (get_java_class_symtab): BLOCK_NAMESPACE instead of
BLOCK_USING.
* dwarf2read.c: Delete variable current_namespace, and replace its
uses by processing_current_namespace (from buildsym.h).
(scan_partial_symbols): Allow empty pdi.name if we're
reading a namespace.
* cp-support.h (struct namespace_info): New struct.
* cp-support.c: Add comment.
* buildsym.h: New variable processing_current_namespace.
* buildsym.c (add_symbol_to_list): Do fast search for
"(anonymous namespace)".
(scan_for_anonymous_namespaces): Delete FIXME.  Convert for loop
into a clearer while loop.
(finish_block): Replace BLOCK_USING by BLOCK_NAMESPACE.
(finish_block): Set block_scope of function blocks rather than
generating using directives that would have a similar effect.
(end_symtab): Set using via block_set_using rather than
BLOCK_USING.
* Makefile.in (symtab.o): Depend on gdb_assert_h.

gdb/ChangeLog.cplus
gdb/Makefile.in
gdb/buildsym.c
gdb/buildsym.h
gdb/cp-support.c
gdb/cp-support.h
gdb/dwarf2read.c
gdb/jv-lang.c
gdb/symtab.c
gdb/symtab.h

index f3d29f7a1928ab568466ffaa09f33b20fec21a7f..4784c6aa6a3d6ab0eaf80c15a4d23d54cea3980a 100644 (file)
@@ -1,3 +1,53 @@
+2002-11-22  David Carlton  <carlton@math.stanford.edu>
+
+       * symtab.h: Add opaque declarations for struct namespace_info and
+       struct obstack.
+       (struct block): The language_specific stuff is now a struct
+       namespace_info rather than a struct using_direct_node.
+       (BLOCK_NAMESPACE): New macro.
+       Delete macro BLOCK_USING.
+       Add declarations for block_using, block_all_usings,
+       block_set_using, block_scope, block_set_scope.
+       * symtab.c: #include "gdb_assert.h"
+       (lookup_symbol_aux): Move minsym stuff inside
+       lookup_symbol_aux_nonlocal, and always do global search via
+       lookup_symbol_aux_using.
+       (lookup_symbol_aux_nonlocal): Do minsym search.
+       (lookup_symbol_aux_using): Calculate usings via block_all_usings;
+       handle namespace scope.
+       (lookup_symbol_aux_using_loop): New function, not to be confused
+       with the previous function of the same name.  (Sorry about that.)
+       (lookup_symbol_namespace): Renamed from
+       lookup_symbol_aux_using_loop.
+       (lookup_symbol_aux_minsyms): Add block_index argument, delete
+       is_a_field_of_this argument, and only check either global or
+       static symbols rather than both of them.
+       (block_using): New function.
+       (block_all_usings): New function.
+       (block_set_using): New function.
+       (block_scope): New function.
+       (block_set_scope): New function.
+       (block_initialize_namespace): New function.
+       * jv-lang.c (get_java_class_symtab): BLOCK_NAMESPACE instead of
+       BLOCK_USING.
+       * dwarf2read.c: Delete variable current_namespace, and replace its
+       uses by processing_current_namespace (from buildsym.h).
+       (scan_partial_symbols): Allow empty pdi.name if we're
+       reading a namespace.
+       * cp-support.h (struct namespace_info): New struct.
+       * cp-support.c: Add comment.
+       * buildsym.h: New variable processing_current_namespace.
+       * buildsym.c (add_symbol_to_list): Do fast search for
+       "(anonymous namespace)".
+       (scan_for_anonymous_namespaces): Delete FIXME.  Convert for loop
+       into a clearer while loop.
+       (finish_block): Replace BLOCK_USING by BLOCK_NAMESPACE.
+       (finish_block): Set block_scope of function blocks rather than
+       generating using directives that would have a similar effect.
+       (end_symtab): Set using via block_set_using rather than
+       BLOCK_USING.
+       * Makefile.in (symtab.o): Depend on gdb_assert_h.
+
 2002-11-01  Daniel Jacobowitz  <drow@mvista.com>
 
        * c-typeprint.c (c_type_print_args): Remove.
index a6172f536735e419ea34820dbaf58464ca40543e..3e2ffd341f0738b85036df29c77b99bb9c8e430e 100644 (file)
@@ -2206,7 +2206,7 @@ symtab.o: symtab.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
        $(gdbcmd_h) $(call_cmds_h) $(gdb_regex_h) $(expression_h) \
        $(language_h) $(demangle_h) $(inferior_h) $(linespec_h) \
        $(filenames_h) $(gdb_obstack_h) $(gdb_string_h) $(gdb_stat_h) \
-       $(cp_abi_h) $(source_h) $(cp_support_h)
+       $(cp_abi_h) $(source_h) $(cp_support_h) $(gdb_assert_h)
 target.o: target.c $(defs_h) $(gdb_string_h) $(target_h) $(gdbcmd_h) \
        $(symtab_h) $(inferior_h) $(bfd_h) $(symfile_h) $(objfiles_h) \
        $(gdb_wait_h) $(dcache_h) $(regcache_h)
index 7bbc0e6f8a87ef94743cf6e7d98b50de54d237fc..6e082186aca2a26eaadd19f440c4330da81121dc 100644 (file)
@@ -160,7 +160,9 @@ add_symbol_to_list (struct symbol *symbol, struct pending **listhead)
   
    if (SYMBOL_LANGUAGE (symbol) == language_cplus
        && !processing_has_namespace_info
-       && SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL)
+       && SYMBOL_CPLUS_DEMANGLED_NAME (symbol) != NULL
+       && strstr (SYMBOL_CPLUS_DEMANGLED_NAME (symbol),
+                 "(anonymous namespace)") != NULL)
      scan_for_anonymous_namespaces (symbol);
 }
 
@@ -175,27 +177,26 @@ static void
 scan_for_anonymous_namespaces (struct symbol *symbol)
 {
   const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
-  const char *beginning, *end;
+  const char *beginning = name;
+  const char *end = cp_find_first_component (beginning);
 
-  /* FIXME: carlton/2002-10-14: Should we do some sort of fast search
-     first to see if the substring "(anonymous namespace)" occurs in
-     name at all?  */
-
-  for (beginning = name, end = cp_find_first_component (name);
-       *end == ':';
-       /* The "+ 2" is for the "::"-.  */
-       beginning = end + 2, end = cp_find_first_component (beginning))
+  while (*end == ':')
     {
       if ((end - beginning) == ANONYMOUS_NAMESPACE_LEN
          && strncmp (beginning, "(anonymous namespace)",
                      ANONYMOUS_NAMESPACE_LEN) == 0)
-       /* We've found a component of the name that's an 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.  */
-       add_using_directive (name,
-                            beginning == name ? 0 : beginning - name - 2,
-                            end - name);
+       {
+         /* We've found a component of the name that's an 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.  */
+         add_using_directive (name,
+                              beginning == name ? 0 : beginning - name - 2,
+                              end - name);
+       }
+      /* The "+ 2" is for the "::".  */
+       beginning = end + 2;
+       end = cp_find_first_component (beginning);
     }
 }
 
@@ -384,7 +385,7 @@ finish_block (struct symbol *symbol, struct pending **listhead,
   BLOCK_END (block) = end;
   /* Superblock filled in when containing block is made */
   BLOCK_SUPERBLOCK (block) = NULL;
-  BLOCK_USING (block) = NULL;
+  BLOCK_NAMESPACE (block) = NULL;
 
   BLOCK_GCC_COMPILED (block) = processing_gcc_compilation;
 
@@ -485,21 +486,38 @@ finish_block (struct symbol *symbol, struct pending **listhead,
          const char *name = SYMBOL_CPLUS_DEMANGLED_NAME (symbol);
          const char *next;
 
-         for (next = cp_find_first_component (name);
-              *next == ':';
-              /* The '+ 2' is to skip the '::'.  */
-              next = cp_find_first_component (next + 2))
+         if (processing_has_namespace_info)
+           block_set_scope (block, processing_current_namespace,
+                            &objfile->symbol_obstack);
+         else
            {
-             BLOCK_USING (block)
-               = cp_add_using_obstack (name, 0, next - name,
-                                       BLOCK_USING (block),
-                                       &objfile->symbol_obstack);
-           }
+             const char *current, *next;
 
-         /* FIMXE: carlton/2002-10-09: Until I understand the
-            possible pitfalls of demangled names a lot better, I want
-            to make sure I'm not running into surprises.  */
-         gdb_assert (*next == '\0');
+             /* FIXME: carlton/2002-11-14: For members of classes,
+                with this include the class name as well?  I don't
+                think that's a problem yet, but it will be.  */
+
+             current = name;
+             next = cp_find_first_component (current);
+             while (*next == ':')
+               {
+                 current = next;
+                 /* The '+ 2' is to skip the '::'.  */
+                 next = cp_find_first_component (current + 2);
+               }
+             if (current == name)
+               block_set_scope (block, "", &objfile->symbol_obstack);
+             else
+               block_set_scope (block,
+                                obsavestring (name, current - name,
+                                              &objfile->symbol_obstack),
+                                &objfile->symbol_obstack);
+             
+             /* FIXME: carlton/2002-10-09: Until I understand the
+                possible pitfalls of demangled names a lot better, I
+                want to make sure I'm not running into surprises.  */
+             gdb_assert (*next == '\0');
+           }
        }
     }
   else
@@ -1063,9 +1081,10 @@ end_symtab (CORE_ADDR end_addr, struct objfile *objfile, int section)
       blockvector = make_blockvector (objfile);
       if (using_list != NULL)
        {
-         BLOCK_USING (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK))
-           = copy_usings_to_obstack (using_list,
-                                     &objfile->symbol_obstack);
+         block_set_using (BLOCKVECTOR_BLOCK (blockvector, STATIC_BLOCK),
+                          copy_usings_to_obstack (using_list,
+                                                  &objfile->symbol_obstack),
+                          &objfile->symbol_obstack);
          using_list = NULL;
        }
     }
index 3b8c16fa19f22938aeed4266a59d0cd2a11e4597..6229e060e0079fd881f84aacc19079d9ef21219e 100644 (file)
@@ -99,6 +99,13 @@ EXTERN unsigned char processing_hp_compilation;
 
 EXTERN unsigned char processing_has_namespace_info;
 
+/* If processing_has_namespace_info is nonzero, this string should
+   contain the name of the current namespace.  Other people shouldn't
+   have to copy it when referring to it, so don't free its previous
+   contents when setting this to a new value.  */
+
+EXTERN const char *processing_current_namespace;
+
 /* Count symbols as they are processed, for error messages.  */
 
 EXTERN unsigned int symnum;
index a13967f9f8292c87055df5abad975f0b57b76218..a5a6db088ee722795ac20daf3d6e5b6a6d111760 100644 (file)
      fairly restrictive set of locations (in particular, they have be
      at depth 0, don't they?).  */
 
+/* NOTE: carlton/2002-10-25: Daniel Jacobowitz came up with an example
+   where operator names don't occur at depth 0.  Sigh.  (It involved a
+   template argument that was a pointer: I hadn't realized that was
+   possible.)  Handling such edge cases does not seem like a
+   high-priority problem to me.  */
+
 /* FIXME: carlton/2002-10-09: Do all the functions here handle all the
    above considerations correctly?  */
 
index bb89c6fe26f7ed097f4d095fecc24489b5c47aa3..70963040f0ab77435eab3c657d95bac0354440b9 100644 (file)
@@ -67,6 +67,16 @@ struct using_direct_node
   struct using_direct_node *next;
 };
 
+/* This is used by struct block to store namespace-related info for
+   C++ files, namely using declarations and the current namespace in
+   scope.  */
+
+struct namespace_info
+{
+  struct using_direct_node *using;
+  const char *scope;
+};
+
 extern struct
 using_direct_node *cp_add_using_obstack (const char *name,
                                         unsigned short outer_length,
index 0dac67fc3dfc594ea7a3fa2304bff06985b7d8cc..f353d4042300d85e691ca6c665a3c6b11536eb3b 100644 (file)
@@ -388,13 +388,6 @@ static struct partial_die_info zeroed_partial_die;
    in buildsym.c.  */
 static struct pending **list_in_scope = &file_symbols;
 
-/* If we're debugging C++ code, this string should contain the name of
-   the current namespace.  Other people shouldn't have to copy it when
-   referring to it, so don't free its previous contents when setting
-   this to a new value.  */
-
-static const char *current_namespace;
-
 /* FIXME: decode_locdesc sets these variables to describe the location
    to the caller.  These ought to be a structure or something.   If
    none of the flags are set, the object lives at the address returned
@@ -1370,7 +1363,9 @@ scan_partial_symbols (char *info_ptr, struct objfile *objfile,
     {
       info_ptr = read_partial_die (&pdi, abfd, info_ptr, cu_header);
 
-      if (pdi.name)
+      /* Anonymous namespaces have no name but are interesting.  */
+
+      if (pdi.name != NULL || pdi.tag == DW_TAG_namespace)
        {
          switch (pdi.tag)
            {
@@ -1632,7 +1627,7 @@ psymtab_to_symtab_1 (struct partial_symtab *pst)
   info_ptr = dwarf_info_buffer + offset;
 
   /* We're in the global namespace.  */
-  current_namespace = "";
+  processing_current_namespace = "";
 
   obstack_init (&dwarf2_tmp_obstack);
   back_to = make_cleanup (dwarf2_free_tmp_obstack, NULL);
@@ -2998,7 +2993,7 @@ static void
 read_namespace (struct die_info *die, struct objfile *objfile,
                const struct comp_unit_head *cu_header)
 {
-  const char *previous_namespace = current_namespace;
+  const char *previous_namespace = processing_current_namespace;
   const char *name = NULL;
   int is_anonymous;
   struct die_info *current_die;
@@ -3021,18 +3016,19 @@ read_namespace (struct die_info *die, struct objfile *objfile,
 
   /* Now build the name of the current namespace.  */
 
-  current_namespace = obconcat (&objfile->symbol_obstack,
-                               previous_namespace,
-                               previous_namespace[0] == '\0' ? "" : "::",
-                               name);
+  processing_current_namespace = obconcat (&objfile->symbol_obstack,
+                                          previous_namespace,
+                                          previous_namespace[0] == '\0'
+                                          ? "" : "::",
+                                          name);
 
   /* If it's an anonymous namespace that we're seeing for the first
      time, add a using directive.  */
 
   if (is_anonymous && dwarf_attr (die, DW_AT_extension) == NULL)
-    add_using_directive (current_namespace,
+    add_using_directive (processing_current_namespace,
                         strlen (previous_namespace),
-                        strlen (current_namespace));
+                        strlen (processing_current_namespace));
   
   
   if (die->has_children)
@@ -3046,7 +3042,7 @@ read_namespace (struct die_info *die, struct objfile *objfile,
        }
     }
 
-  current_namespace = previous_namespace;
+  processing_current_namespace = previous_namespace;
 }
 
 /* Extract all information from a DW_TAG_pointer_type DIE and add to
index 03bf565da8a8a1f28116b772746eda8be21c5f4a..40044a23c93e9bfa2af7d02a7b8936959772c5ca 100644 (file)
@@ -111,7 +111,7 @@ get_java_class_symtab (void)
       BLOCK_END (bl) = 0;
       BLOCK_FUNCTION (bl) = NULL;
       BLOCK_SUPERBLOCK (bl) = NULL;
-      BLOCK_USING (bl) = NULL;
+      BLOCK_NAMESPACE (bl) = NULL;
       BLOCK_GCC_COMPILED (bl) = 0;
       BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK) = bl;
 
index c1d7d3cfc72de5f934caeb1fd75d2f119f29332a..5ca6b437e89a367edfc1eea27f816f777dd8ff5a 100644 (file)
@@ -50,6 +50,7 @@
 #include <ctype.h>
 #include "cp-abi.h"
 #include "cp-support.h"
+#include "gdb_assert.h"
 
 /* Prototypes for local functions */
 
@@ -119,22 +120,30 @@ struct symbol *lookup_symbol_aux_using (const char *name,
                                        struct symtab **symtab);
 
 static
-struct symbol *lookup_symbol_aux_using_loop (const char *prefix,
-                                            int prefix_len,
-                                            const char *rest,
-                                            struct using_direct_node *using,
+struct symbol *lookup_symbol_aux_using_loop (const char *name,
                                             const char *mangled_name,
                                             namespace_enum namespace,
-                                            struct symtab **symtab);
+                                            struct symtab **symtab,
+                                            const char *scope,
+                                            int scope_len,
+                                            struct using_direct_node *using);
 
 static
-struct symbol *lookup_symbol_aux_minsyms (const char *name,
+struct symbol *lookup_symbol_namespace (const char *prefix,
+                                       int prefix_len,
+                                       const char *rest,
+                                       struct using_direct_node *using,
+                                       const char *mangled_name,
+                                       namespace_enum namespace,
+                                       struct symtab **symtab);
+
+static
+struct symbol *lookup_symbol_aux_minsyms (int block_index,
+                                         const char *name,
                                          const char *mangled_name,
                                          const namespace_enum namespace,
-                                         int *is_a_field_of_this,
                                          struct symtab **symtab);
 
-
 static struct symbol *find_active_alias (struct symbol *sym, CORE_ADDR addr);
 
 /* This flag is used in hppa-tdep.c, and set in hp-symtab-read.c */
@@ -154,6 +163,9 @@ static void symtab_symbol_info (char *, namespace_enum, int);
 
 static void overload_list_add_symbol (struct symbol *sym, char *oload_name);
 
+static void block_initialize_namespace (struct block *block,
+                                       struct obstack *obstack);
+
 void _initialize_symtab (void);
 
 /* */
@@ -842,84 +854,35 @@ lookup_symbol_aux (const char *name, const char *mangled_name,
        }
     }
 
-  /* Now search all global blocks.  Do the symtab's first, then
-     check the psymtab's. If a psymtab indicates the existence
-     of the desired name as a global, then do psymtab-to-symtab
-     conversion on the fly and return the found symbol. */
+  /* Now search all global blocks.  Do the symtab's first, then the
+     minsyms, then check the psymtab's. If minsyms or psymtabs
+     indicate the existence of the desired name as a global, then
+     generate the appropriate symtab on the fly and return the found
+     symbol.
 
-  sym = lookup_symbol_aux_nonlocal (GLOBAL_BLOCK, name, mangled_name,
-                                   namespace, symtab);
-  if (sym != NULL)
-    return sym;
-
-  /* If we're in the C++ case, check to see if the symbol is defined
-     in a namespace accessible via a "using" declaration.  */
+     We do this from within lookup_symbol_aux_using: that will apply
+     appropriate using directives in the C++ case.  But it works fine
+     in the non-C++ case, too.  */
 
-  /* FIXME: carlton/2002-10-10: is "is_a_field_of_this" always
-     non-NULL if we're in the C++ case?  Maybe we should always do
-     this, and delete the two previous searches: this will always
-     search the global namespace, after all.  */
-
-  if (is_a_field_of_this)
-    {
-      sym = lookup_symbol_aux_using (name, mangled_name, block, namespace,
-                                    symtab);
-      if (sym != NULL)
-       return sym;
-    }
+  /* NOTE: carlton/2002-10-22: Is it worthwhile to try to figure out
+     whether or not we're in the C++ case?  Doing
+     lookup_symbol_aux_using won't slow things down significantly in
+     the general case, though: other parts of this function are much,
+     much more expensive.  */
 
-#ifndef HPUXHPPA
-
-  /* Check for the possibility of the symbol being a function or a
-     mangled variable that is stored in one of the minimal symbol
-     tables.  Eventually, all global symbols might be resolved in this
-     way.  */
-
-  sym = lookup_symbol_aux_minsyms (name, mangled_name,
-                                  namespace, is_a_field_of_this,
-                                  symtab);
+  sym = lookup_symbol_aux_using (name, mangled_name, block, namespace,
+                                symtab);
   if (sym != NULL)
     return sym;
 
-#endif
-
   /* Now search all static file-level symbols.  Not strictly correct,
-     but more useful than an error.  Do the symtabs first, then check
-     the psymtabs.  If a psymtab indicates the existence of the
-     desired name as a file-level static, then do psymtab-to-symtab
-     conversion on the fly and return the found symbol. */
+     but more useful than an error.  */
 
   sym = lookup_symbol_aux_nonlocal (STATIC_BLOCK, name, mangled_name,
                                    namespace, symtab);
   if (sym != NULL)
     return sym;
 
-#ifdef HPUXHPPA
-
-  /* Check for the possibility of the symbol being a function or a
-     global variable that is stored in one of the minimal symbol
-     tables.  The "minimal symbol table" is built from linker-supplied
-     info.
-
-     RT: I moved this check to last, after the complete search of the
-     global (p)symtab's and static (p)symtab's. For HP-generated
-     symbol tables, this check was causing a premature exit from
-     lookup_symbol with NULL return, and thus messing up symbol
-     lookups of things like "c::f". It seems to me a check of the
-     minimal symbol table ought to be a last resort in any case. I'm
-     vaguely worried about the comment within
-     lookup_symbol_aux_minsyms which talks about FORTRAN routines
-     "foo_" though... is it saying we need to do the "minsym" check
-     before the static check in this case?  */
-
-  sym = lookup_symbol_aux_minsyms (name, mangled_name,
-                                  namespace, is_a_field_of_this,
-                                  symtab);
-  if (sym != NULL)
-    return sym;
-
-#endif
-
   if (symtab != NULL)
     *symtab = NULL;
   return NULL;
@@ -975,9 +938,6 @@ lookup_symbol_aux_local (const char *name, const char *mangled_name,
    STATIC_BLOCK, depending on whether or not we want to search global
    symbols or static symbols.  */
 
-/* FIXME: carlton/2002-10-11: Should this also do some minsym
-   lookup?  */
-
 static struct symbol *
 lookup_symbol_aux_nonlocal (int block_index,
                            const char *name,
@@ -992,8 +952,63 @@ lookup_symbol_aux_nonlocal (int block_index,
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_aux_psymtabs (block_index, name, mangled_name,
-                                    namespace, symtab);
+#ifndef HPUXHPPA
+  sym = lookup_symbol_aux_minsyms (block_index, name, mangled_name,
+                                  namespace, symtab);
+  if (sym != NULL)
+    return sym;
+#endif
+
+  sym = lookup_symbol_aux_psymtabs (block_index, name, mangled_name,
+                                   namespace, symtab);
+  if (sym != NULL)
+    return sym;
+
+#ifdef HPUXHPPA
+
+  /* FIXME: carlton/2002-10-28: The following comment was present in
+     lookup_symbol_aux before I broke it up: at that time, the HP
+     search order for nonlocal stuff was global symtab, global
+     psymtab, static symtab, static psymtab, global and static
+     minsyms.  (The minsyms are stored so that it's just as easy to do
+     global and static searches of them at the same time.)  Now it's
+     global symtab, global psymtab, global minsyms, static symtab,
+     static psymtab, static minsyms.  Also, it's now impossible for a
+     global minsym search to cause a NULL return by itself: if a
+     minsym search returns NULL, then the next search after that is
+     still performed.
+
+     Given that that's the case, I'm pretty sure that my search order
+     is safe; indeed, given that the comment below warns against
+     premature NULL returns, it even seems plausible to me that we can
+     treat HP symbol tables the same as non-HP symbol tables.  It
+     would be great if somebody who has access to HP machines (or,
+     even better, who understands the reason behind the HP special
+     case in the first place) could check on this.
+
+     But there's still the comment about "foo_" symbols in
+     lookup_symbol_aux_minsyms which I really don't understand, sigh.
+     _Should_ a minsym lookup sometimes be able to force a NULL return
+     from lookup_symbol?  */
+
+  /* RT: I moved this check to last, after the complete search of the
+     global (p)symtab's and static (p)symtab's. For HP-generated
+     symbol tables, this check was causing a premature exit from
+     lookup_symbol with NULL return, and thus messing up symbol
+     lookups of things like "c::f". It seems to me a check of the
+     minimal symbol table ought to be a last resort in any case. I'm
+     vaguely worried about the comment within
+     lookup_symbol_aux_minsyms which talks about FORTRAN routines
+     "foo_" though... is it saying we need to do the "minsym" check
+     before the static check in this case?  */
+
+  sym = lookup_symbol_aux_minsyms (block_index, name, mangled_name,
+                                  namespace, symtab);
+  if (sym != NULL)
+    return sym;
+#endif
+
+  return NULL;
 }
 
 /* Check to see if the symbol is defined in one of the symtabs.
@@ -1092,32 +1107,69 @@ lookup_symbol_aux_psymtabs (int block_index, const char *name,
 /* This function gathers using directives from BLOCK and its
    superblocks, and then searches for symbols in the global namespace
    by trying to apply those various using directives.  */
+
 static struct symbol *lookup_symbol_aux_using (const char *name,
                                               const char *mangled_name,
                                               const struct block *block,
                                               const namespace_enum namespace,
                                               struct symtab **symtab)
 {
-  struct using_direct_node *using = NULL;
+  struct using_direct_node *using;
+  const char *scope;
   struct symbol *sym;
 
-  while (block != NULL)
-    {
-      using = cp_copy_usings (BLOCK_USING (block), using);
-      block = BLOCK_SUPERBLOCK (block);
-    }
-
-  sym = lookup_symbol_aux_using_loop ("", 0, name, using, mangled_name,
-                                     namespace, symtab);
+  using = block_all_usings (block);
+  scope = block_scope (block);
+  
+  sym = lookup_symbol_aux_using_loop (name, mangled_name, namespace, symtab,
+                                     scope, 0, using);
   cp_free_usings (using);
   
   return sym;
 }
 
+/* Look up NAME in the namespaces given by SCOPE and its initial
+   prefixes, applying using directives given by USING; only consider
+   prefixes that are at least as long as SCOPE_LEN, however.  Look up
+   longest prefixes first.  */
+
+static struct
+symbol *lookup_symbol_aux_using_loop (const char *name,
+                                     const char *mangled_name,
+                                     namespace_enum namespace,
+                                     struct symtab **symtab,
+                                     const char *scope,
+                                     int scope_len,
+                                     struct using_direct_node *using)
+{
+  if (scope[scope_len] != '\0')
+    {
+      struct symbol *sym;
+      int next_component;
+      int new_scope_len = scope_len;
+
+      /* If the current scope is followed by "::", skip past that.  */
+      if (new_scope_len != 0)
+       {
+         gdb_assert (scope[new_scope_len] == ':');
+         new_scope_len += 2;
+       }
+      next_component = cp_find_first_component (scope + new_scope_len) - scope;
+      sym = lookup_symbol_aux_using_loop (name, mangled_name, namespace,
+                                         symtab, scope, next_component,
+                                         using);
+      if (sym != NULL)
+       return sym;
+    }
+
+  return lookup_symbol_namespace (scope, scope_len, name, using,
+                                 mangled_name, namespace, symtab);
+}
+
 /* This tries to look up REST in the namespace given by the initial
    substring of PREFIX of length PREFIX_LEN.
 
-   Basically, assume that we have using directives adding A to the
+   For example, assume that we have using directives adding A to the
    global namespace, adding A::inner to namespace A, and adding B to
    the global namespace.  Then, when looking up a symbol "foo", we
    want to recurse by looking up stuff in A::foo and seeing which
@@ -1138,14 +1190,19 @@ static struct symbol *lookup_symbol_aux_using (const char *name,
    namespaces first-class objects.  (Which is certainly a good idea
    for other reasons, but it will take a little while.)  */
 
+/* NOTE: carlton/2002-11-19: This is optimistically called
+   lookup_symbol_namespace instead of lookup_symbol_aux_namespace in
+   hopes that it or something like it might eventually be useful
+   outside of lookup_symbol.  */
+
 static struct symbol *
-lookup_symbol_aux_using_loop (const char *prefix,
-                             int prefix_len,
-                             const char *rest,
-                             struct using_direct_node *using,
-                             const char *mangled_name,
-                             namespace_enum namespace,
-                             struct symtab **symtab)
+lookup_symbol_namespace (const char *prefix,
+                        int prefix_len,
+                        const char *rest,
+                        struct using_direct_node *using,
+                        const char *mangled_name,
+                        namespace_enum namespace,
+                        struct symtab **symtab)
 {
   struct using_direct_node *current;
   struct symbol *sym;
@@ -1179,14 +1236,13 @@ lookup_symbol_aux_using_loop (const char *prefix,
              if (*new_rest == ':')
                new_rest += 2;
 
-             sym = lookup_symbol_aux_using_loop
-               (current->current->name,
-                current->current->inner_length,
-                new_rest,
-                using,
-                mangled_name,
-                namespace,
-                symtab);
+             sym = lookup_symbol_namespace (current->current->name,
+                                            current->current->inner_length,
+                                            new_rest,
+                                            using,
+                                            mangled_name,
+                                            namespace,
+                                            symtab);
              if (sym != NULL)
                return sym;
            }
@@ -1223,10 +1279,9 @@ lookup_symbol_aux_using_loop (const char *prefix,
    way.  */
 
 static struct symbol *
-lookup_symbol_aux_minsyms (const char *name,
+lookup_symbol_aux_minsyms (int block_index, const char *name,
                           const char *mangled_name,
                           const namespace_enum namespace,
-                          int *is_a_field_of_this,
                           struct symtab **symtab)
 {
   struct symbol *sym;
@@ -1250,7 +1305,30 @@ lookup_symbol_aux_minsyms (const char *name,
             know about demangled names, but we were given a mangled
             name...  */
 
-         /* We first use the address in the msymbol to try to locate
+         /* First, check to see that the symbol looks like it's
+            global or static (depending on what we were asked to look
+            for).  */
+
+         /* NOTE: carlton/2002-10-28: lookup_minimal_symbol gives
+            preference to global symbols over static symbols, so if
+            block_index is STATIC_BLOCK then this might well miss
+            static symbols that are shadowed by global symbols.  But
+            that's okay: this is only called with block_index equal
+            to STATIC_BLOCK if a global search has failed.  */
+
+         switch (MSYMBOL_TYPE (msymbol))
+           {
+           case mst_file_text:
+           case mst_file_data:
+           case mst_file_bss:
+             if (block_index == GLOBAL_BLOCK)
+               return NULL;
+           default:
+             if (block_index == STATIC_BLOCK)
+               return NULL;
+           }
+         
+         /* We next use the address in the msymbol to try to locate
             the appropriate symtab. Note that find_pc_sect_symtab()
             has a side-effect of doing psymtab-to-symtab expansion,
             for the found symtab.  */
@@ -1260,7 +1338,7 @@ lookup_symbol_aux_minsyms (const char *name,
            {
              /* This is a function which has a symtab for its address.  */
              bv = BLOCKVECTOR (s);
-             block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
+             block = BLOCKVECTOR_BLOCK (bv, block_index);
 
              /* This call used to pass `SYMBOL_NAME (msymbol)' as the
                 `name' argument to lookup_block_symbol.  But the name
@@ -1269,14 +1347,16 @@ lookup_symbol_aux_minsyms (const char *name,
                 unmangled name.  */
              sym =
                lookup_block_symbol (block, name, mangled_name, namespace);
-             /* We kept static functions in minimal symbol table as well as
-                in static scope. We want to find them in the symbol table. */
-             if (!sym)
-               {
-                 block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-                 sym = lookup_block_symbol (block, name,
-                                            mangled_name, namespace);
-               }
+
+             /* FIXME: carlton/2002-10-28: this next comment dates
+                from when this code was part of lookup_symbol_aux, so
+                this return could return NULL from lookup_symbol_aux.
+                Are there really situations where we want a minimal
+                symbol lookup to be able to force a NULL return from
+                lookup_symbol?  If so, maybe the thing to do would be
+                to have lookup_symbol_aux_minsym to set a
+                minsym_found flag, and to have lookup_symbol_aux only
+                do the psymtab search if that flag is zero.  */
 
              /* sym == 0 if symbol was found in the minimal symbol table
                 but not in the symtab.
@@ -1297,13 +1377,15 @@ lookup_symbol_aux_minsyms (const char *name,
            }
          else if (MSYMBOL_TYPE (msymbol) != mst_text
                   && MSYMBOL_TYPE (msymbol) != mst_file_text
-                  && !STREQ (name, SYMBOL_NAME (msymbol)))
+                  && strcmp (name, SYMBOL_NAME (msymbol)) != 0)
            {
              /* This is a mangled variable, look it up by its
                 mangled name.  */
-             return lookup_symbol_aux (SYMBOL_NAME (msymbol), mangled_name,
-                                       NULL, namespace, is_a_field_of_this,
-                                       symtab);
+             return lookup_symbol_aux_nonlocal (block_index,
+                                                SYMBOL_NAME (msymbol),
+                                                mangled_name,
+                                                namespace,
+                                                symtab);
            }
        }
     }
@@ -3275,6 +3357,96 @@ contained_in (struct block *a, struct block *b)
   return BLOCK_START (a) >= BLOCK_START (b)
     && BLOCK_END (a) <= BLOCK_END (b);
 }
+
+/* Now come some functions designed to deal with C++ namespace issues.
+   The accessors are safe to use even in the non-C++ case.  */
+
+/* This returns the using directives associated to BLOCK (but _not_
+   its parents), if any.  */
+
+struct using_direct_node *
+block_using (const struct block *block)
+{
+  if (BLOCK_NAMESPACE (block) == NULL)
+    return NULL;
+  else
+    return BLOCK_NAMESPACE (block)->using;
+}
+
+/* This returns the using directives associated to BLOCK and its
+   parents, if any.  The resulting structure must be freed by calling
+   cp_free_usings on it.  */
+
+struct using_direct_node *
+block_all_usings (const struct block *block)
+{
+  struct using_direct_node *using = NULL;
+
+  while (block != NULL)
+    {
+      using = cp_copy_usings (block_using (block), using);
+      block = BLOCK_SUPERBLOCK (block);
+    }
+
+  return using;
+}
+
+/* Set block_using (BLOCK) to USING; if needed, allocate memory via
+   OBSTACK.  */
+
+void
+block_set_using (struct block *block, struct using_direct_node *using,
+                struct obstack *obstack)
+{
+  block_initialize_namespace (block, obstack);
+
+  BLOCK_NAMESPACE (block)->using = using;
+}
+
+/* This returns the namespace that BLOCK is enclosed in, or "" if it
+   isn't enclosed in a namespace at all.  This travels the chain of
+   superblocks looking for a scope, if necessary.  */
+
+const char *
+block_scope (const struct block *block)
+{
+  for (; block != NULL; block = BLOCK_SUPERBLOCK (block))
+    {
+      if (BLOCK_NAMESPACE (block) != NULL
+         && BLOCK_NAMESPACE (block)->scope != NULL)
+       return BLOCK_NAMESPACE (block)->scope;
+    }
+
+  return "";
+}
+
+/* Set block_scope (BLOCK) to SCOPE; if needed, allocate memory via
+   OBSTACK.  (It won't make a copy of SCOPE, however, so that already
+   has to be allocated correctly.)  */
+
+void
+block_set_scope (struct block *block, const char *scope,
+                struct obstack *obstack)
+{
+  block_initialize_namespace (block, obstack);
+
+  BLOCK_NAMESPACE (block)->scope = scope;
+}
+
+/* If BLOCK_NAMESPACE (block) is NULL, allocate it via OBSTACK and
+   ititialize its members to zero.  */
+
+static void
+block_initialize_namespace (struct block *block, struct obstack *obstack)
+{
+  if (BLOCK_NAMESPACE (block) == NULL)
+    {
+      BLOCK_NAMESPACE (block)
+       = obstack_alloc (obstack, sizeof (struct namespace_info));
+      BLOCK_NAMESPACE (block)->using = NULL;
+    }
+}
+
 \f
 
 /* Helper routine for make_symbol_completion_list.  */
index 063a93042c1db48413e0dbdcc5543837566632c3..df51e2af641eefd71f416a503c0eb66130b9e707 100644 (file)
@@ -25,7 +25,9 @@
 
 /* Opaque declarations.  */
 struct obstack;
+struct namespace_info;
 struct using_direct_node;
+struct obstack;
 
 /* Don't do this; it means that if some .o's are compiled with GNU C
    and some are not (easy to do accidentally the way we configure
@@ -374,12 +376,11 @@ struct block
   {
     struct
     {
-      /* Contains information about what using directives or other
-        similar features are added by this block.  This should always
-        be NULL for global blocks: if there are using directives that
-        affect an entire file, put it in the static block.  */
+      /* Contains information about namespace-related info relevant to
+        this block: using directives and the current namespace
+        scope.  */
       
-      struct using_direct_node *using;
+      struct namespace_info *namespace;
     }
     cplus_specific;
   }
@@ -430,7 +431,7 @@ struct block
 #define BLOCK_END(bl)          (bl)->endaddr
 #define BLOCK_FUNCTION(bl)     (bl)->function
 #define BLOCK_SUPERBLOCK(bl)   (bl)->superblock
-#define BLOCK_USING(bl)                (bl)->language_specific.cplus_specific.using
+#define BLOCK_NAMESPACE(bl)    (bl)->language_specific.cplus_specific.namespace
 #define BLOCK_GCC_COMPILED(bl) (bl)->gcc_compile_flag
 #define BLOCK_HASHTABLE(bl)    (bl)->hashtable
 
@@ -1144,6 +1145,19 @@ extern int find_pc_line_pc_range (CORE_ADDR, CORE_ADDR *, CORE_ADDR *);
 
 extern int contained_in (struct block *, struct block *);
 
+extern struct using_direct_node *block_using (const struct block *);
+
+extern struct using_direct_node *block_all_usings (const struct block *block);
+
+extern void block_set_using (struct block *block,
+                            struct using_direct_node *using,
+                            struct obstack *obstack);
+
+extern const char *block_scope (const struct block *block);
+
+extern void block_set_scope (struct block *block, const char *scope,
+                            struct obstack *obstack);
+
 extern void reread_symbols (void);
 
 extern struct type *lookup_transparent_type (const char *);