This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

RFA/symtab: Let search_symbols find exact matches


This patch renames search_symbols to search_symbols_aux, and lets it take an
argument that specified regex or exact (well, strcmp_iw) matching.  Then
search_symbols becomes a wrapper.

The new function is used by make_symbol_overload_list, which shaves 50% time
off of some tests in the C++ directory if your system libc has debugging
symbols; it removes the bogusity where all psymtabs were converted to
symtabs during overload resolution.  Whew.  This cuts memory for
namespace.exp from 70MB to 7MB, allowing some of my hardware to actually run
the test without crashing.

Hopefully at some point I can extend search_symbols_aux to also do prefix
matching and use it to speed up make_symbol_completion_list, but there are
some subtleties - like, in that context we don't need to read in psymbols. 
And the sorting requirements are different.

Symtab maintainers, is this OK?

-- 
Daniel Jacobowitz
MontaVista Software                         Debian GNU/Linux Developer

2003-02-10  Daniel Jacobowitz  <drow@mvista.com>

	* symtab.c (enum sym_match_kind): New.
	(symbol_matches_kind, symbol_matches_pattern): New functions.
	(search_symbols_aux): Renamed from search_symbols.  Accept an
	enum sym_match_kind argument.  Use symbol_matches_kind and
	symbol_matches_pattern.  Move file_matches call out of the
	per-symbol loop.
	(search_symbols): New function, calling search_symbols_aux.
	(make_symbol_overload_list): Use search_symbols_aux.

Index: symtab.c
===================================================================
RCS file: /big/fsf/rsync/src-cvs/src/gdb/symtab.c,v
retrieving revision 1.87
diff -u -p -r1.87 symtab.c
--- symtab.c	4 Feb 2003 18:07:01 -0000	1.87
+++ symtab.c	10 Feb 2003 15:53:22 -0000
@@ -2787,8 +2787,77 @@ sort_search_symbols (struct symbol_searc
   return symp;
 }
 
-/* Search the symbol table for matches to the regular expression REGEXP,
-   returning the results in *MATCHES.
+/* Possible match styles for search_symbols_aux.  */
+
+enum sym_match_method {
+  sym_match_regex,
+  sym_match_exact
+};
+
+static inline int
+symbol_matches_kind (enum address_class aclass, namespace_enum kind)
+{
+  /* If the address class does not match the requested namespace, return 0.  */
+  switch (kind)
+    {
+    case VARIABLES_NAMESPACE:
+      if (aclass == LOC_TYPEDEF || aclass == LOC_BLOCK || aclass == LOC_CONST)
+	return 0;
+      break;
+
+    case FUNCTIONS_NAMESPACE:
+      if (aclass != LOC_BLOCK)
+	return 0;
+      break;
+
+    case TYPES_NAMESPACE:
+      if (aclass != LOC_TYPEDEF)
+	return 0;
+      break;
+
+    case METHODS_NAMESPACE:
+      if (aclass != LOC_BLOCK)
+	return 0;
+      break;
+
+    default:
+      internal_error (__FILE__, __LINE__,
+		      "Invalid kind passed to symbol_matches_pattern");
+    }
+
+  return 1;
+}
+
+static inline int
+symbol_matches_pattern (const char *sym_name, const char *sym_demangled_name,
+			const char *pattern, enum sym_match_method how)
+{
+  if (pattern == NULL)
+    return 1;
+
+  switch (how)
+    {
+    case sym_match_regex:
+      if (re_exec (sym_name)
+	  || (sym_demangled_name && re_exec (sym_demangled_name)))
+	return 1;
+      break;
+
+    case sym_match_exact:
+      if (strcmp_iw (sym_name, pattern) == 0
+	  || (sym_demangled_name
+	      && strcmp_iw (sym_demangled_name, pattern) == 0))
+	return 1;
+      break;
+    }
+
+  return 0;
+}
+
+/* Search the symbol table for matches to the pattern PATTERN,
+   returning the results in *MATCHES.  If HOW is sym_match_regex,
+   PATTERN is a regular expression; if HOW is sym_match_exact, PATTERN
+   is an exact string (almost: strcmp_iw is used).
 
    Only symbols of KIND are searched:
    FUNCTIONS_NAMESPACE - search all functions
@@ -2800,11 +2869,12 @@ sort_search_symbols (struct symbol_searc
    free_search_symbols should be called when *MATCHES is no longer needed.
 
    The results are sorted locally; each symtab's global and static blocks are
-   separately alphabetized.
- */
-void
-search_symbols (char *regexp, namespace_enum kind, int nfiles, char *files[],
-		struct symbol_search **matches)
+   separately alphabetized.  */
+
+static void
+search_symbols_aux (char *pattern, namespace_enum kind, int nfiles,
+		    char *files[], struct symbol_search **matches,
+		    enum sym_match_method how)
 {
   register struct symtab *s;
   register struct partial_symtab *ps;
@@ -2851,14 +2921,14 @@ search_symbols (char *regexp, namespace_
   sr = *matches = NULL;
   tail = NULL;
 
-  if (regexp != NULL)
+  if (pattern != NULL)
     {
       /* Make sure spacing is right for C++ operators.
          This is just a courtesy to make the matching less sensitive
          to how many spaces the user leaves between 'operator'
          and <TYPENAME> or <OPERATOR>. */
       char *opend;
-      char *opname = operator_chars (regexp, &opend);
+      char *opname = operator_chars (pattern, &opend);
       if (*opname)
 	{
 	  int fix = -1;		/* -1 means ok; otherwise number of spaces needed. */
@@ -2879,16 +2949,17 @@ search_symbols (char *regexp, namespace_
 	    {
 	      char *tmp = (char *) alloca (8 + fix + strlen (opname) + 1);
 	      sprintf (tmp, "operator%.*s%s", fix, " ", opname);
-	      regexp = tmp;
+	      pattern = tmp;
 	    }
 	}
 
-      if (0 != (val = re_comp (regexp)))
-	error ("Invalid regexp (%s): %s", val, regexp);
+      if (how == sym_match_regex)
+	if (0 != (val = re_comp (pattern)))
+	  error ("Invalid regexp (%s): %s", val, pattern);
     }
 
   /* Search through the partial symtabs *first* for all symbols
-     matching the regexp.  That way we don't have to reproduce all of
+     matching the pattern.  That way we don't have to reproduce all of
      the machinery below. */
 
   ALL_PSYMTABS (objfile, ps)
@@ -2899,6 +2970,9 @@ search_symbols (char *regexp, namespace_
     if (ps->readin)
       continue;
 
+    if (! file_matches (ps->filename, files, nfiles))
+      continue;
+
     gbound = objfile->global_psymbols.list + ps->globals_offset + ps->n_global_syms;
     sbound = objfile->static_psymbols.list + ps->statics_offset + ps->n_static_syms;
     bound = gbound;
@@ -2925,13 +2999,10 @@ search_symbols (char *regexp, namespace_
 
 	    /* If it would match (logic taken from loop below)
 	       load the file and go on to the next one */
-	    if (file_matches (ps->filename, files, nfiles)
-		&& ((regexp == NULL || SYMBOL_MATCHES_REGEXP (*psym))
-		    && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (*psym) != LOC_TYPEDEF
-			 && SYMBOL_CLASS (*psym) != LOC_BLOCK)
-			|| (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK)
-			|| (kind == TYPES_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_TYPEDEF)
-			|| (kind == METHODS_NAMESPACE && SYMBOL_CLASS (*psym) == LOC_BLOCK))))
+	    if (symbol_matches_kind (SYMBOL_CLASS (*psym), kind)
+		&& symbol_matches_pattern (SYMBOL_NAME (*psym),
+					   SYMBOL_DEMANGLED_NAME (*psym),
+					   pattern, how))
 	      {
 		PSYMTAB_TO_SYMTAB (ps);
 		keep_going = 0;
@@ -2963,7 +3034,9 @@ search_symbols (char *regexp, namespace_
 	    MSYMBOL_TYPE (msymbol) == ourtype3 ||
 	    MSYMBOL_TYPE (msymbol) == ourtype4)
 	  {
-	    if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
+	    if (symbol_matches_pattern (SYMBOL_NAME (msymbol),
+					SYMBOL_DEMANGLED_NAME (msymbol),
+					pattern, how))
 	      {
 		if (0 == find_pc_symtab (SYMBOL_VALUE_ADDRESS (msymbol)))
 		  {
@@ -3000,6 +3073,9 @@ search_symbols (char *regexp, namespace_
 
   ALL_SYMTABS (objfile, s)
   {
+    if (! file_matches (s->filename, files, nfiles))
+      continue;
+
     bv = BLOCKVECTOR (s);
     /* Often many files share a blockvector.
        Scan each blockvector only once so that
@@ -3015,14 +3091,10 @@ search_symbols (char *regexp, namespace_
 	  ALL_BLOCK_SYMBOLS (b, j, sym)
 	    {
 	      QUIT;
-	      if (file_matches (s->filename, files, nfiles)
-		  && ((regexp == NULL || SYMBOL_MATCHES_REGEXP (sym))
-		      && ((kind == VARIABLES_NAMESPACE && SYMBOL_CLASS (sym) != LOC_TYPEDEF
-			   && SYMBOL_CLASS (sym) != LOC_BLOCK
-			   && SYMBOL_CLASS (sym) != LOC_CONST)
-			  || (kind == FUNCTIONS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK)
-			  || (kind == TYPES_NAMESPACE && SYMBOL_CLASS (sym) == LOC_TYPEDEF)
-			  || (kind == METHODS_NAMESPACE && SYMBOL_CLASS (sym) == LOC_BLOCK))))
+	      if (symbol_matches_kind (SYMBOL_CLASS (sym), kind)
+		  && symbol_matches_pattern (SYMBOL_NAME (sym),
+					     SYMBOL_DEMANGLED_NAME (sym),
+					     pattern, how))
 		{
 		  /* match */
 		  psr = (struct symbol_search *) xmalloc (sizeof (struct symbol_search));
@@ -3070,7 +3142,9 @@ search_symbols (char *regexp, namespace_
 	    MSYMBOL_TYPE (msymbol) == ourtype3 ||
 	    MSYMBOL_TYPE (msymbol) == ourtype4)
 	  {
-	    if (regexp == NULL || SYMBOL_MATCHES_REGEXP (msymbol))
+	    if (symbol_matches_pattern (SYMBOL_NAME (msymbol),
+					SYMBOL_DEMANGLED_NAME (msymbol),
+					pattern, how))
 	      {
 		/* Functions:  Look up by address. */
 		if (kind != FUNCTIONS_NAMESPACE ||
@@ -3108,6 +3182,16 @@ search_symbols (char *regexp, namespace_
     discard_cleanups (old_chain);
 }
 
+/* A wrapper for search_symbols_aux, above, which treats PATTERN as a
+   regular expression.  */
+
+void
+search_symbols (char *pattern, namespace_enum kind, int nfiles,
+		char *files[], struct symbol_search **matches)
+{
+  search_symbols_aux (pattern, kind, nfiles, files, matches, sym_match_regex);
+}
+
 /* Helper function for symtab_symbol_info, this function uses
    the data returned from search_symbols() to print information
    regarding the match to gdb_stdout.
@@ -4005,6 +4089,8 @@ overload_list_add_symbol (struct symbol 
 struct symbol **
 make_symbol_overload_list (struct symbol *fsym)
 {
+  struct symbol_search *matches, *matchp;
+
   register struct symbol *sym;
   register struct symtab *s;
   register struct partial_symtab *ps;
@@ -4035,88 +4121,20 @@ make_symbol_overload_list (struct symbol
   sym_return_val = (struct symbol **) xmalloc ((sym_return_val_size + 1) * sizeof (struct symbol *));
   sym_return_val[0] = NULL;
 
-  /* Look through the partial symtabs for all symbols which begin
-     by matching OLOAD_NAME.  Make sure we read that symbol table in. */
-
-  ALL_PSYMTABS (objfile, ps)
-  {
-    struct partial_symbol **psym;
+  search_symbols_aux (oload_name, FUNCTIONS_NAMESPACE, 0, NULL, &matches,
+		      sym_match_exact);
 
-    /* If the psymtab's been read in we'll get it when we search
-       through the blockvector.  */
-    if (ps->readin)
-      continue;
-
-    for (psym = objfile->global_psymbols.list + ps->globals_offset;
-	 psym < (objfile->global_psymbols.list + ps->globals_offset
-		 + ps->n_global_syms);
-	 psym++)
-      {
-	/* If interrupted, then quit. */
-	QUIT;
-        /* This will cause the symbol table to be read if it has not yet been */
-        s = PSYMTAB_TO_SYMTAB (ps);
-      }
-
-    for (psym = objfile->static_psymbols.list + ps->statics_offset;
-	 psym < (objfile->static_psymbols.list + ps->statics_offset
-		 + ps->n_static_syms);
-	 psym++)
-      {
-	QUIT;
-        /* This will cause the symbol table to be read if it has not yet been */
-        s = PSYMTAB_TO_SYMTAB (ps);
-      }
-  }
-
-  /* Search upwards from currently selected frame (so that we can
-     complete on local vars.  */
-
-  for (b = get_selected_block (0); b != NULL; b = BLOCK_SUPERBLOCK (b))
+  matchp = matches;
+  while (matchp)
     {
-      if (!BLOCK_SUPERBLOCK (b))
-	{
-	  surrounding_static_block = b;		/* For elimination of dups */
-	}
-
-      /* Also catch fields of types defined in this places which match our
-         text string.  Only complete on types visible from current context. */
-
-      ALL_BLOCK_SYMBOLS (b, i, sym)
-	{
-	  overload_list_add_symbol (sym, oload_name);
-	}
+      if (matchp->symbol)
+	overload_list_add_symbol (matchp->symbol, oload_name);
+      matchp = matchp->next;
     }
 
-  /* Go through the symtabs and check the externs and statics for
-     symbols which match.  */
-
-  ALL_SYMTABS (objfile, s)
-  {
-    QUIT;
-    b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), GLOBAL_BLOCK);
-    ALL_BLOCK_SYMBOLS (b, i, sym)
-      {
-	overload_list_add_symbol (sym, oload_name);
-      }
-  }
-
-  ALL_SYMTABS (objfile, s)
-  {
-    QUIT;
-    b = BLOCKVECTOR_BLOCK (BLOCKVECTOR (s), STATIC_BLOCK);
-    /* Don't do this block twice.  */
-    if (b == surrounding_static_block)
-      continue;
-    ALL_BLOCK_SYMBOLS (b, i, sym)
-      {
-	overload_list_add_symbol (sym, oload_name);
-      }
-  }
-
   xfree (oload_name);
-
-  return (sym_return_val);
+  free_search_symbols (matches);
+  return sym_return_val;
 }
 
 /* End of overload resolution functions */


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]