Rework symbol searches to move Ada-specific stuff to ada-lang.c.
authorPaul N. Hilfinger <hilfinger@adacore.com>
Thu, 7 Oct 2010 07:13:51 +0000 (07:13 +0000)
committerPaul N. Hilfinger <hilfinger@adacore.com>
Thu, 7 Oct 2010 07:13:51 +0000 (07:13 +0000)
This is a clean-up of some of our symbol-lookup machinery to pull some
kludgy Ada-specific definitions out of psymtab.c.  In place of
map_ada_symtabs and ada_lookup_partial_symbol, we have a method
map_matching_symbols, which searches through all symbol tables and
partial symbol tables looking for a symbol that matches according to
a matching function that is passed as a parameter. This requires some
care, because partial symbol tables speed up searches by binary search,
while full symbol tables use hashing. To call map_matching_symbols, therefore,
you may need to supply both a matching function that is compatible with the
dictionary hash function and an ordering relation that is compatible with
strcmp_iw, which is used to order partial symbol tables.

Having added this general routine to psymtab.c, we use it in ada-lang.c
to rework add_non_local_symbols (now renamed add_nonlocal_symbols).

Changelog:

    gdb/

    * ada-lang.c (full_match): Declare.
    (ada_match_name): Rename to match_name (we should avoid prefixing static
    symbols with "ada_").
    (match_name): New name for ada_match_name.
    (struct ada_psym_data): Remove and replace with...
    (struct match_data): User data for map_matching_symbols.
    (ada_add_psyms): Remove.
    (aux_add_nonlocal_symbols): New function, used as callback for
    map_matching_symbols.
    (compare_names): Ordering function adopted from strcmp_iw for Ada-encoded
    symbols.
    (ada_add_non_local_symbols): Rename to add_nonlocal_symbols.
    (add_nonlocal_symbols): Renamed from ada_add_non_local_symbols.
    Rework to use map_matching_symbols instead of map_ada_symtabs.
    (ada_lookup_symbol_list): Use add_nonlocal_symbols.
    * psymtab.c: Include dependency on dictionary.h.
    (match_partial_symbol): New function.
    (ada_lookup_partial_symbol): Remove.
    (map_block): New function, auxiliary to map_matching_symbols_psymtab.
    (map_matching_symbols_psymtab): New function.
    (psym_functions): Replace map_ada_symtabs with map_matching_symbols_psymtab.
    * symfile.h: Replace map_ada_symtabs definition with map_matching_symbols.

gdb/ChangeLog
gdb/ada-lang.c
gdb/dwarf2read.c
gdb/psymtab.c
gdb/symfile.h

index 9e5a615..803edfe 100644 (file)
@@ -1,24 +1,49 @@
+2010-10-07  Paul Hilfinger  <hilfinger@adacore.com>
+
+        * ada-lang.c (full_match): Declare.
+        (ada_match_name): Rename to match_name (we should avoid prefixing static
+        symbols with "ada_").
+        (match_name): New name for ada_match_name.
+        (struct ada_psym_data): Remove and replace with...
+        (struct match_data): User data for map_matching_symbols.
+        (ada_add_psyms): Remove.
+        (aux_add_nonlocal_symbols): New function, used as callback for
+        map_matching_symbols.
+        (compare_names): Ordering function adopted from strcmp_iw for Ada-encoded
+        symbols.
+        (ada_add_non_local_symbols): Rename to add_nonlocal_symbols.
+        (add_nonlocal_symbols): Renamed from ada_add_non_local_symbols.
+        Rework to use map_matching_symbols instead of map_ada_symtabs.
+        (ada_lookup_symbol_list): Use add_nonlocal_symbols.
+        * psymtab.c: Include dependency on dictionary.h.
+        (match_partial_symbol): New function.
+        (ada_lookup_partial_symbol): Remove.
+        (map_block): New function, auxiliary to map_matching_symbols_psymtab.
+        (map_matching_symbols_psymtab): New function.
+        (psym_functions): Replace map_ada_symtabs with map_matching_symbols_psymtab.
+        * symfile.h: Replace map_ada_symtabs definition with map_matching_symbols.
+
 2010-10-06  Paul Hilfinger  <hilfinger@adacore.com>
 
        * ada-lang.c (ada_match_name): Use new API for wild_match.
-       (wild_match): Change API to be consistent with that of strcmp_iw;
-       return 0 for a match, and switch operand order.
-       (full_match): New function.
-       (ada_add_block_symbols): Use dict_iter_match_{first,next} for
-       matching to allow use of hashing.
-       * dictionary.c (struct dict_vector): Generalize iter_name_first,
-       iter_name_next ot iter_match_first, iter_match_next.
-       (iter_name_first_hashed): Replace with iter_match_first_hashed.
-       (iter_name_next_hashed): Replace with iter_match_next_hashed.
-       (iter_name_first_linear): Replace with iter_match_first_linear.
-       (iter_name_next_linear): Replace with iter_match_next_linear.
-       (dict_iter_name_first): Re-implement to use dict_iter_match_first.
-       (dict_iter_name_next): Re-implement to use dict_iter_match_next.
-       (dict_iter_match_first): New function.
-       (dict_iter_match_next): New function.
-       (dict_hash): New function.
-       * dictionary.h (dict_iter_match_first, dict_iter_match_next): Declare.
-       * psymtab.c (ada_lookup_partial_symbol): Use new wild_match API.
+       (wild_match): Change API to be consistent with that of strcmp_iw;
+       return 0 for a match, and switch operand order.
+       (full_match): New function.
+       (ada_add_block_symbols): Use dict_iter_match_{first,next} for
+       matching to allow use of hashing.
+       * dictionary.c (struct dict_vector): Generalize iter_name_first,
+       iter_name_next ot iter_match_first, iter_match_next.
+       (iter_name_first_hashed): Replace with iter_match_first_hashed.
+       (iter_name_next_hashed): Replace with iter_match_next_hashed.
+       (iter_name_first_linear): Replace with iter_match_first_linear.
+       (iter_name_next_linear): Replace with iter_match_next_linear.
+       (dict_iter_name_first): Re-implement to use dict_iter_match_first.
+       (dict_iter_name_next): Re-implement to use dict_iter_match_next.
+       (dict_iter_match_first): New function.
+       (dict_iter_match_next): New function.
+       (dict_hash): New function.
+       * dictionary.h (dict_iter_match_first, dict_iter_match_next): Declare.
+       * psymtab.c (ada_lookup_partial_symbol): Use new wild_match API.
 
 2010-10-06  Doug Evans  <dje@google.com>
 
index c111e40..ea71ea2 100644 (file)
@@ -103,6 +103,8 @@ static int ada_type_match (struct type *, struct type *, int);
 
 static int ada_args_match (struct symbol *, struct value **, int);
 
+static int full_match (const char *, const char *);
+
 static struct value *make_array_descriptor (struct type *, struct value *);
 
 static void ada_add_block_symbols (struct obstack *,
@@ -1254,7 +1256,7 @@ ada_la_decode (const char *encoded, int options)
    either argument is NULL.  */
 
 static int
-ada_match_name (const char *sym_name, const char *name, int wild)
+match_name (const char *sym_name, const char *name, int wild)
 {
   if (sym_name == NULL || name == NULL)
     return 0;
@@ -4267,7 +4269,7 @@ ada_lookup_simple_minsym (const char *name)
 
   ALL_MSYMBOLS (objfile, msymbol)
   {
-    if (ada_match_name (SYMBOL_LINKAGE_NAME (msymbol), name, wild_match)
+    if (match_name (SYMBOL_LINKAGE_NAME (msymbol), name, wild_match)
         && MSYMBOL_TYPE (msymbol) != mst_solib_trampoline)
       return msymbol;
   }
@@ -4627,28 +4629,91 @@ ada_add_local_symbols (struct obstack *obstackp, const char *name,
 }
 
 /* An object of this type is used as the user_data argument when
-   calling the map_ada_symtabs method.  */
+   calling the map_matching_symbols method.  */
 
-struct ada_psym_data
+struct match_data
 {
+  struct objfile *objfile;
   struct obstack *obstackp;
-  const char *name;
-  domain_enum domain;
-  int global;
-  int wild_match;
+  struct symbol *arg_sym;
+  int found_sym;
 };
 
-/* Callback function for map_ada_symtabs.  */
+/* A callback for add_matching_symbols that adds SYM, found in BLOCK,
+   to a list of symbols.  DATA0 is a pointer to a struct match_data *
+   containing the obstack that collects the symbol list, the file that SYM
+   must come from, a flag indicating whether a non-argument symbol has
+   been found in the current block, and the last argument symbol
+   passed in SYM within the current block (if any).  When SYM is null,
+   marking the end of a block, the argument symbol is added if no
+   other has been found.  */
 
-static void
-ada_add_psyms (struct objfile *objfile, struct symtab *s, void *user_data)
+static int
+aux_add_nonlocal_symbols (struct block *block, struct symbol *sym, void *data0)
 {
-  struct ada_psym_data *data = user_data;
-  const int block_kind = data->global ? GLOBAL_BLOCK : STATIC_BLOCK;
+  struct match_data *data = (struct match_data *) data0;
+  
+  if (sym == NULL)
+    {
+      if (!data->found_sym && data->arg_sym != NULL) 
+       add_defn_to_vec (data->obstackp,
+                        fixup_symbol_section (data->arg_sym, data->objfile),
+                        block);
+      data->found_sym = 0;
+      data->arg_sym = NULL;
+    }
+  else 
+    {
+      if (SYMBOL_CLASS (sym) == LOC_UNRESOLVED)
+       return 0;
+      else if (SYMBOL_IS_ARGUMENT (sym))
+       data->arg_sym = sym;
+      else
+       {
+         data->found_sym = 1;
+         add_defn_to_vec (data->obstackp,
+                          fixup_symbol_section (sym, data->objfile),
+                          block);
+       }
+    }
+  return 0;
+}
+
+/* Compare STRING1 to STRING2, with results as for strcmp.
+   Compatible with strcmp_iw in that strcmp_iw (STRING1, STRING2) <= 0
+   implies compare_names (STRING1, STRING2) (they may differ as to
+   what symbols compare equal).  */
 
-  ada_add_block_symbols (data->obstackp,
-                        BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), block_kind),
-                        data->name, data->domain, objfile, data->wild_match);
+static int
+compare_names (const char *string1, const char *string2)
+{
+  while (*string1 != '\0' && *string2 != '\0')
+    {
+      if (isspace (*string1) || isspace (*string2))
+       return strcmp_iw_ordered (string1, string2);
+      if (*string1 != *string2)
+       break;
+      string1 += 1;
+      string2 += 1;
+    }
+  switch (*string1)
+    {
+    case '(':
+      return strcmp_iw_ordered (string1, string2);
+    case '_':
+      if (*string2 == '\0')
+       {
+         if (is_name_suffix (string2))
+           return 0;
+         else
+           return -1;
+       }
+    default:
+      if (*string2 == '(')
+       return strcmp_iw_ordered (string1, string2);
+      else
+       return *string1 - *string2;
+    }
 }
 
 /* Add to OBSTACKP all non-local symbols whose name and domain match
@@ -4656,27 +4721,43 @@ ada_add_psyms (struct objfile *objfile, struct symtab *s, void *user_data)
    symbols if GLOBAL is non-zero, or on STATIC_BLOCK symbols otherwise.  */
 
 static void
-ada_add_non_local_symbols (struct obstack *obstackp, const char *name,
-                           domain_enum domain, int global,
-                           int is_wild_match)
+add_nonlocal_symbols (struct obstack *obstackp, const char *name,
+                     domain_enum domain, int global,
+                     int is_wild_match)
 {
   struct objfile *objfile;
-  struct ada_psym_data data;
+  struct match_data data;
 
   data.obstackp = obstackp;
-  data.name = name;
-  data.domain = domain;
-  data.global = global;
-  data.wild_match = is_wild_match;
+  data.arg_sym = NULL;
 
   ALL_OBJFILES (objfile)
-  {
-    if (objfile->sf)
-      objfile->sf->qf->map_ada_symtabs (objfile, wild_match, is_name_suffix,
-                                       ada_add_psyms, name,
-                                       global, domain,
-                                       is_wild_match, &data);
-  }
+    {
+      data.objfile = objfile;
+
+      if (is_wild_match)
+       objfile->sf->qf->map_matching_symbols (name, domain, objfile, global,
+                                              aux_add_nonlocal_symbols, &data,
+                                              wild_match, NULL);
+      else
+       objfile->sf->qf->map_matching_symbols (name, domain, objfile, global,
+                                              aux_add_nonlocal_symbols, &data,
+                                              full_match, compare_names);
+    }
+
+  if (num_defns_collected (obstackp) == 0 && global && !is_wild_match)
+    {
+      ALL_OBJFILES (objfile)
+        {
+         char *name1 = alloca (strlen (name) + sizeof ("_ada_"));
+         strcpy (name1, "_ada_");
+         strcpy (name1 + sizeof ("_ada_") - 1, name);
+         data.objfile = objfile;
+         objfile->sf->qf->map_matching_symbols (name1, domain, objfile, global,
+                                                aux_add_nonlocal_symbols, &data,
+                                                full_match, compare_names);
+       }
+    }          
 }
 
 /* Find symbols in DOMAIN matching NAME0, in BLOCK0 and enclosing
@@ -4753,15 +4834,15 @@ ada_lookup_symbol_list (const char *name0, const struct block *block0,
 
   /* Search symbols from all global blocks.  */
  
-  ada_add_non_local_symbols (&symbol_list_obstack, name, namespace, 1,
-                             wild_match);
+  add_nonlocal_symbols (&symbol_list_obstack, name, namespace, 1,
+                       wild_match);
 
   /* Now add symbols from all per-file blocks if we've gotten no hits
      (not strictly correct, but perhaps better than an error).  */
 
   if (num_defns_collected (&symbol_list_obstack) == 0)
-    ada_add_non_local_symbols (&symbol_list_obstack, name, namespace, 0,
-                               wild_match);
+    add_nonlocal_symbols (&symbol_list_obstack, name, namespace, 0,
+                         wild_match);
 
 done:
   ndefns = num_defns_collected (&symbol_list_obstack);
@@ -5062,10 +5143,13 @@ wild_match (const char *name, const char *patn)
     }
 }
 
+/* Returns 0 iff symbol name SYM_NAME matches SEARCH_NAME, apart from
+   informational suffix.  */
+
 static int
 full_match (const char *sym_name, const char *search_name)
 {
-  return !ada_match_name (sym_name, search_name, 0);
+  return !match_name (sym_name, search_name, 0);
 }
 
 
@@ -5118,7 +5202,7 @@ ada_add_block_symbols (struct obstack *obstackp,
   else
     {
      for (sym = dict_iter_match_first (BLOCK_DICT (block), name,
-                                       full_match, &iter);
+                                      full_match, &iter);
           sym != NULL; sym = dict_iter_match_next (name, full_match, &iter))
       {
         if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
index 02304cb..5aeb739 100644 (file)
@@ -2371,16 +2371,16 @@ dw2_find_symbol_file (struct objfile *objfile, const char *name)
 }
 
 static void
-dw2_map_ada_symtabs (struct objfile *objfile,
-                    int (*wild_match) (const char *, const char *),
-                    int (*is_name_suffix) (const char *),
-                    void (*callback) (struct objfile *,
-                                      struct symtab *, void *),
-                    const char *name, int global,
-                    domain_enum namespace, int wild,
-                    void *data)
-{
-  /* For now, we don't support Ada.  Still the function can be called if the
+dw2_map_matching_symbols (const char * name, domain_enum namespace,
+                         struct objfile *objfile, int global,
+                         int (*callback) (struct block *,
+                                          struct symbol *, void *),
+                         void *data,
+                         int (*match) (const char *, const char *),
+                         int (*ordered_compare) (const char *,
+                                                 const char *))
+{
+  /* Currently unimplemented; used for Ada.  The function can be called if the
      current language is Ada for a non-Ada objfile using GNU index.  As Ada
      does not look for non-Ada symbols this function should just return.  */
 }
@@ -2560,7 +2560,7 @@ const struct quick_symbol_functions dwarf2_gdb_index_functions =
   dw2_expand_all_symtabs,
   dw2_expand_symtabs_with_filename,
   dw2_find_symbol_file,
-  dw2_map_ada_symtabs,
+  dw2_map_matching_symbols,
   dw2_expand_symtabs_matching,
   dw2_find_pc_sect_symtab,
   dw2_map_symbol_names,
index eac3e1a..95f102b 100644 (file)
@@ -32,6 +32,7 @@
 #include "command.h"
 #include "readline/readline.h"
 #include "gdb_regex.h"
+#include "dictionary.h"
 
 #ifndef DEV_TTY
 #define DEV_TTY "/dev/tty"
@@ -46,7 +47,15 @@ struct psymbol_bcache
 #define PSYMTAB_TO_SYMTAB(pst)  \
     ((pst) -> symtab != NULL ? (pst) -> symtab : psymtab_to_symtab (pst))
 
-/* Lookup a partial symbol.  */
+static struct partial_symbol *match_partial_symbol (struct partial_symtab *,
+                                                   int,
+                                                   const char *, domain_enum,
+                                                   int (*) (const char *,
+                                                            const char *),
+                                                   int (*) (const char *,
+                                                            const char *));
+
+
 static struct partial_symbol *lookup_partial_symbol (struct partial_symtab *,
                                                     const char *, int,
                                                     domain_enum);
@@ -426,6 +435,85 @@ lookup_symbol_aux_psymtabs (struct objfile *objfile,
   return NULL;
 }
 
+/* Look in PST for a symbol in DOMAIN whose name matches NAME.  Search
+   the global block of PST if GLOBAL, and otherwise the static block.
+   MATCH is the comparison operation that returns true iff MATCH (s,
+   NAME), where s is a SYMBOL_SEARCH_NAME.  If ORDERED_COMPARE is
+   non-null, the symbols in the block are assumed to be ordered
+   according to it (allowing binary search).  It must be compatible
+   with MATCH.  Returns the symbol, if found, and otherwise NULL.  */
+
+static struct partial_symbol *
+match_partial_symbol (struct partial_symtab *pst, int global,
+                     const char *name, domain_enum domain,
+                     int (*match) (const char *, const char *),
+                     int (*ordered_compare) (const char *, const char *))
+{
+  struct partial_symbol **start, **psym;
+  struct partial_symbol **top, **real_top, **bottom, **center;
+  int length = (global ? pst->n_global_syms : pst->n_static_syms);
+  int do_linear_search = 1;
+
+  if (length == 0)
+      return NULL;
+  start = (global ?
+          pst->objfile->global_psymbols.list + pst->globals_offset :
+          pst->objfile->static_psymbols.list + pst->statics_offset);
+
+  if (global && ordered_compare)  /* Can use a binary search.  */
+    {
+      do_linear_search = 0;
+
+      /* Binary search.  This search is guaranteed to end with center
+         pointing at the earliest partial symbol whose name might be
+         correct.  At that point *all* partial symbols with an
+         appropriate name will be checked against the correct
+         domain.  */
+
+      bottom = start;
+      top = start + length - 1;
+      real_top = top;
+      while (top > bottom)
+       {
+         center = bottom + (top - bottom) / 2;
+         gdb_assert (center < top);
+         if (!do_linear_search
+             && (SYMBOL_LANGUAGE (*center) == language_java))
+           do_linear_search = 1;
+         if (ordered_compare (SYMBOL_SEARCH_NAME (*center), name) >= 0)
+           top = center;
+         else
+           bottom = center + 1;
+       }
+      gdb_assert (top == bottom);
+
+      while (top <= real_top
+            && match (SYMBOL_SEARCH_NAME (*top), name) == 0)
+       {
+         if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
+                                    SYMBOL_DOMAIN (*top), domain))
+           return *top;
+         top++;
+       }
+    }
+
+  /* Can't use a binary search or else we found during the binary search that
+     we should also do a linear search.  */
+
+  if (do_linear_search)
+    {
+      for (psym = start; psym < start + length; psym++)
+       {
+         if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
+                                    SYMBOL_DOMAIN (*psym), domain)
+             && match (SYMBOL_SEARCH_NAME (*psym), name) == 0)
+           return *psym;
+       }
+    }
+
+  return NULL;
+}
+
 static void
 pre_expand_symtabs_matching_psymtabs (struct objfile *objfile,
                                      int kind, const char *name,
@@ -435,7 +523,7 @@ pre_expand_symtabs_matching_psymtabs (struct objfile *objfile,
 }
 
 /* Look, in partial_symtab PST, for symbol whose natural name is NAME.
-   Check the global symbols if GLOBAL, the static symbols if not. */
+   Check the global symbols if GLOBAL, the static symbols if not.  */
 
 static struct partial_symbol *
 lookup_partial_symbol (struct partial_symtab *pst, const char *name,
@@ -473,7 +561,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
          if (!(center < top))
            internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
          if (!do_linear_search
-             && (SYMBOL_LANGUAGE (*center) == language_java))
+             && SYMBOL_LANGUAGE (*center) == language_java)
            {
              do_linear_search = 1;
            }
@@ -500,7 +588,7 @@ lookup_partial_symbol (struct partial_symtab *pst, const char *name,
     }
 
   /* Can't use a binary search or else we found during the binary search that
-     we should also do a linear search. */
+     we should also do a linear search.  */
 
   if (do_linear_search)
     {
@@ -967,174 +1055,72 @@ find_symbol_file_from_partial (struct objfile *objfile, const char *name)
   return NULL;
 }
 
-/* Look, in partial_symtab PST, for symbol NAME in given namespace.
-   Check the global symbols if GLOBAL, the static symbols if not.
-   Do wild-card match if WILD.  */
+/*  For all symbols, s, in BLOCK that are in NAMESPACE and match NAME
+    according to the function MATCH, call CALLBACK(BLOCK, s, DATA).
+    BLOCK is assumed to come from OBJFILE.  Returns 1 iff CALLBACK
+    ever returns non-zero, and otherwise returns 0.  */
 
-static struct partial_symbol *
-ada_lookup_partial_symbol (struct partial_symtab *pst, const char *name,
-                           int global, domain_enum namespace, int wild,
-                          int (*wild_match) (const char *, const char *),
-                          int (*is_name_suffix) (const char *))
+static int
+map_block (const char *name, domain_enum namespace, struct objfile *objfile,
+          struct block *block,
+          int (*callback) (struct block *, struct symbol *, void *),
+          void *data,
+          int (*match) (const char *, const char *))
 {
-  struct partial_symbol **start;
-  int name_len = strlen (name);
-  int length = (global ? pst->n_global_syms : pst->n_static_syms);
-  int i;
+  struct dict_iterator iter;
+  struct symbol *sym;
 
-  if (length == 0)
+  for (sym = dict_iter_match_first (BLOCK_DICT (block), name, match, &iter);
+       sym != NULL; sym = dict_iter_match_next (name, match, &iter))
     {
-      return (NULL);
+      if (symbol_matches_domain (SYMBOL_LANGUAGE (sym), 
+                                SYMBOL_DOMAIN (sym), namespace))
+       {
+         if (callback (block, sym, data))
+           return 1;
+       }
     }
 
-  start = (global ?
-           pst->objfile->global_psymbols.list + pst->globals_offset :
-           pst->objfile->static_psymbols.list + pst->statics_offset);
-
-  if (wild)
-    {
-      for (i = 0; i < length; i += 1)
-        {
-          struct partial_symbol *psym = start[i];
-
-          if (symbol_matches_domain (SYMBOL_LANGUAGE (psym),
-                                     SYMBOL_DOMAIN (psym), namespace)
-              && (*wild_match) (SYMBOL_LINKAGE_NAME (psym), name) == 0)
-            return psym;
-        }
-      return NULL;
-    }
-  else
-    {
-      if (global)
-        {
-          int U;
-
-          i = 0;
-          U = length - 1;
-          while (U - i > 4)
-            {
-              int M = (U + i) >> 1;
-              struct partial_symbol *psym = start[M];
-
-              if (SYMBOL_LINKAGE_NAME (psym)[0] < name[0])
-                i = M + 1;
-              else if (SYMBOL_LINKAGE_NAME (psym)[0] > name[0])
-                U = M - 1;
-              else if (strcmp (SYMBOL_LINKAGE_NAME (psym), name) < 0)
-                i = M + 1;
-              else
-                U = M;
-            }
-        }
-      else
-        i = 0;
-
-      while (i < length)
-        {
-          struct partial_symbol *psym = start[i];
-
-          if (symbol_matches_domain (SYMBOL_LANGUAGE (psym),
-                                     SYMBOL_DOMAIN (psym), namespace))
-            {
-              int cmp = strncmp (name, SYMBOL_LINKAGE_NAME (psym), name_len);
-
-              if (cmp < 0)
-                {
-                  if (global)
-                    break;
-                }
-              else if (cmp == 0
-                       && (*is_name_suffix) (SYMBOL_LINKAGE_NAME (psym)
-                                            + name_len))
-                return psym;
-            }
-          i += 1;
-        }
-
-      if (global)
-        {
-          int U;
-
-          i = 0;
-          U = length - 1;
-          while (U - i > 4)
-            {
-              int M = (U + i) >> 1;
-              struct partial_symbol *psym = start[M];
-
-              if (SYMBOL_LINKAGE_NAME (psym)[0] < '_')
-                i = M + 1;
-              else if (SYMBOL_LINKAGE_NAME (psym)[0] > '_')
-                U = M - 1;
-              else if (strcmp (SYMBOL_LINKAGE_NAME (psym), "_ada_") < 0)
-                i = M + 1;
-              else
-                U = M;
-            }
-        }
-      else
-        i = 0;
-
-      while (i < length)
-        {
-          struct partial_symbol *psym = start[i];
-
-          if (symbol_matches_domain (SYMBOL_LANGUAGE (psym),
-                                     SYMBOL_DOMAIN (psym), namespace))
-            {
-              int cmp;
-
-              cmp = (int) '_' - (int) SYMBOL_LINKAGE_NAME (psym)[0];
-              if (cmp == 0)
-                {
-                  cmp = strncmp ("_ada_", SYMBOL_LINKAGE_NAME (psym), 5);
-                  if (cmp == 0)
-                    cmp = strncmp (name, SYMBOL_LINKAGE_NAME (psym) + 5,
-                                   name_len);
-                }
-
-              if (cmp < 0)
-                {
-                  if (global)
-                    break;
-                }
-              else if (cmp == 0
-                       && (*is_name_suffix) (SYMBOL_LINKAGE_NAME (psym)
-                                            + name_len + 5))
-                return psym;
-            }
-          i += 1;
-        }
-    }
-  return NULL;
+  return 0;
 }
 
+/*  Psymtab version of map_matching_symbols.  See its definition in
+    the definition of quick_symbol_functions in symfile.h.  */
+
 static void
-map_ada_symtabs (struct objfile *objfile,
-                int (*wild_match) (const char *, const char *),
-                int (*is_name_suffix) (const char *),
-                void (*callback) (struct objfile *, struct symtab *, void *),
-                const char *name, int global, domain_enum namespace, int wild,
-                void *data)
+map_matching_symbols_psymtab (const char *name, domain_enum namespace,
+                             struct objfile *objfile, int global,
+                             int (*callback) (struct block *,
+                                              struct symbol *, void *),
+                             void *data,
+                             int (*match) (const char *, const char *),
+                             int (*ordered_compare) (const char *,
+                                                     const char *))
 {
+  const int block_kind = global ? GLOBAL_BLOCK : STATIC_BLOCK;
   struct partial_symtab *ps;
 
   ALL_OBJFILE_PSYMTABS (objfile, ps)
     {
       QUIT;
       if (ps->readin
-         || ada_lookup_partial_symbol (ps, name, global, namespace, wild,
-                                       wild_match, is_name_suffix))
+         || match_partial_symbol (ps, global, name, namespace, match,
+                                  ordered_compare))
        {
          struct symtab *s = PSYMTAB_TO_SYMTAB (ps);
+         struct block *block;
 
          if (s == NULL || !s->primary)
            continue;
-         (*callback) (objfile, s, data);
+         block = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), block_kind);
+         if (map_block (name, namespace, objfile, block,
+                        callback, data, match))
+           return;
+         if (callback (block, NULL, data))
+           return;
        }
     }
-}
+}          
 
 static void
 expand_symtabs_matching_via_partial (struct objfile *objfile,
@@ -1220,7 +1206,7 @@ const struct quick_symbol_functions psym_functions =
   expand_partial_symbol_tables,
   read_psymtabs_with_filename,
   find_symbol_file_from_partial,
-  map_ada_symtabs,
+  map_matching_symbols_psymtab,
   expand_symtabs_matching_via_partial,
   find_pc_sect_symtab_from_partial,
   map_symbol_names_psymtab,
index f9b4e01..c9f4e65 100644 (file)
@@ -212,21 +212,31 @@ struct quick_symbol_functions
      named NAME.  If no such symbol exists in OBJFILE, return NULL.  */
   const char *(*find_symbol_file) (struct objfile *objfile, const char *name);
 
-  /* This method is specific to Ada.  It walks the partial symbol
-     tables of OBJFILE looking for a name match.  WILD_MATCH and
-     IS_NAME_SUFFIX are predicate functions that the implementation
-     may call to check for a match.
-
-     This function is completely ad hoc and new implementations should
-     refer to the psymtab implementation to see what to do.  */
-  void (*map_ada_symtabs) (struct objfile *objfile,
-                          int (*wild_match) (const char *, const char *),
-                          int (*is_name_suffix) (const char *),
-                          void (*callback) (struct objfile *,
-                                            struct symtab *, void *),
-                          const char *name, int global,
-                          domain_enum namespace, int wild,
-                          void *data);
+  /* Find global or static symbols in all tables that are in NAMESPACE 
+     and for which MATCH (symbol name, NAME) == 0, passing each to 
+     CALLBACK, reading in partial symbol symbol tables as needed.  Look
+     through global symbols if GLOBAL and otherwise static symbols.  
+     Passes NAME, NAMESPACE, and DATA to CALLBACK with each symbol
+     found.  After each block is processed, passes NULL to CALLBACK.
+     MATCH must be weaker than strcmp_iw in the sense that
+     strcmp_iw(x,y) == 0 --> MATCH(x,y) == 0.  ORDERED_COMPARE, if
+     non-null, must be an ordering relation compatible with strcmp_iw
+     in the sense that  
+            strcmp(x,y) == 0 --> ORDERED_COMPARE(x,y) == 0 
+     and 
+            strcmp(x,y) <= 0 --> ORDERED_COMPARE(x,y) <= 0
+     (allowing strcmp(x,y) < 0 while ORDERED_COMPARE(x, y) == 0). 
+     CALLBACK returns 0 to indicate that the scan should continue, or
+     non-zero to indicate that the scan should be terminated.  */
+
+  void (*map_matching_symbols) (const char *name, domain_enum namespace,
+                               struct objfile *, int global,
+                               int (*callback) (struct block *,
+                                                struct symbol *, void *),
+                               void *data,
+                               int (*match) (const char *, const char *),
+                               int (*ordered_compare) (const char *,
+                                                       const char *));
 
   /* Expand all symbol tables in OBJFILE matching some criteria.