This is the mail archive of the gdb-prs@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]

pending/1077: RFA/symtab: Let search_symbols find exact matches


>Number:         1077
>Category:       pending
>Synopsis:       RFA/symtab: Let search_symbols find exact matches
>Confidential:   yes
>Severity:       serious
>Priority:       medium
>Responsible:    unassigned
>State:          open
>Class:          change-request
>Submitter-Id:   unknown
>Arrival-Date:   Thu Feb 20 00:38:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     
>Release:        
>Organization:
>Environment:
>Description:
 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 at mvista dot 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 */
 
>How-To-Repeat:
>Fix:
>Release-Note:
>Audit-Trail:
>Unformatted:


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