* linespec.c (find_linespec_symbols): Call find_function_symbols

first, and then call lookup_prefix_sym/find_method.
This commit is contained in:
Doug Evans 2013-03-11 18:24:59 +00:00
parent 39086a0e13
commit cc81e1c673
2 changed files with 80 additions and 61 deletions

View File

@ -1,3 +1,9 @@
2013-03-11 Doug Evans <dje@google.com>
Keith Seitz <keiths@redhat.com>
* linespec.c (find_linespec_symbols): Call find_function_symbols
first, and then call lookup_prefix_sym/find_method.
2013-03-11 Pedro Alves <palves@redhat.com>
* charset.c (convert_between_encodings): Don't cast between

View File

@ -3073,10 +3073,9 @@ find_linespec_symbols (struct linespec_state *state,
VEC (symbolp) **symbols,
VEC (minsym_and_objfile_d) **minsyms)
{
char *klass, *method, *canon;
const char *lookup_name, *last, *p, *scope_op;
struct cleanup *cleanup;
VEC (symbolp) *classes;
char *canon;
const char *lookup_name;
volatile struct gdb_exception except;
cleanup = demangle_for_lookup (name, state->language->la_language,
@ -3096,75 +3095,89 @@ find_linespec_symbols (struct linespec_state *state,
cleanup = make_cleanup (xfree, canon);
}
/* See if we can find a scope operator and break this symbol
name into namespaces${SCOPE_OPERATOR}class_name and method_name. */
scope_op = "::";
p = find_toplevel_string (lookup_name, scope_op);
if (p == NULL)
/* It's important to not call expand_symtabs_matching unnecessarily
as it can really slow things down (by unnecessarily expanding
potentially 1000s of symtabs, which when debugging some apps can
cost 100s of seconds). Avoid this to some extent by *first* calling
find_function_symbols, and only if that doesn't find anything
*then* call find_method. This handles two important cases:
1) break (anonymous namespace)::foo
2) break class::method where method is in class (and not a baseclass) */
find_function_symbols (state, file_symtabs, lookup_name,
symbols, minsyms);
/* If we were unable to locate a symbol of the same name, try dividing
the name into class and method names and searching the class and its
baseclasses. */
if (VEC_empty (symbolp, *symbols)
&& VEC_empty (minsym_and_objfile_d, *minsyms))
{
/* No C++ scope operator. Try Java. */
scope_op = ".";
char *klass, *method;
const char *last, *p, *scope_op;
VEC (symbolp) *classes;
/* See if we can find a scope operator and break this symbol
name into namespaces${SCOPE_OPERATOR}class_name and method_name. */
scope_op = "::";
p = find_toplevel_string (lookup_name, scope_op);
}
last = NULL;
while (p != NULL)
{
last = p;
p = find_toplevel_string (p + strlen (scope_op), scope_op);
}
/* If no scope operator was found, lookup the name as a symbol. */
if (last == NULL)
{
find_function_symbols (state, file_symtabs, lookup_name,
symbols, minsyms);
do_cleanups (cleanup);
return;
}
/* NAME points to the class name.
LAST points to the method name. */
klass = xmalloc ((last - lookup_name + 1) * sizeof (char));
make_cleanup (xfree, klass);
strncpy (klass, lookup_name, last - lookup_name);
klass[last - lookup_name] = '\0';
/* Skip past the scope operator. */
last += strlen (scope_op);
method = xmalloc ((strlen (last) + 1) * sizeof (char));
make_cleanup (xfree, method);
strcpy (method, last);
/* Find a list of classes named KLASS. */
classes = lookup_prefix_sym (state, file_symtabs, klass);
make_cleanup (VEC_cleanup (symbolp), &classes);
if (!VEC_empty (symbolp, classes))
{
/* Now locate a list of suitable methods named METHOD. */
TRY_CATCH (except, RETURN_MASK_ERROR)
if (p == NULL)
{
find_method (state, file_symtabs, klass, method, classes,
symbols, minsyms);
/* No C++ scope operator. Try Java. */
scope_op = ".";
p = find_toplevel_string (lookup_name, scope_op);
}
/* If successful, we're done. If NOT_FOUND_ERROR
was not thrown, rethrow the exception that we did get.
Otherwise, fall back to looking up the entire name as a symbol.
This can happen with namespace::function. */
if (except.reason >= 0)
last = NULL;
while (p != NULL)
{
last = p;
p = find_toplevel_string (p + strlen (scope_op), scope_op);
}
/* If no scope operator was found, there is nothing more we can do;
we already attempted to lookup the entire name as a symbol
and failed. */
if (last == NULL)
{
do_cleanups (cleanup);
return;
}
else if (except.error != NOT_FOUND_ERROR)
throw_exception (except);
/* LOOKUP_NAME points to the class name.
LAST points to the method name. */
klass = xmalloc ((last - lookup_name + 1) * sizeof (char));
make_cleanup (xfree, klass);
strncpy (klass, lookup_name, last - lookup_name);
klass[last - lookup_name] = '\0';
/* Skip past the scope operator. */
last += strlen (scope_op);
method = xmalloc ((strlen (last) + 1) * sizeof (char));
make_cleanup (xfree, method);
strcpy (method, last);
/* Find a list of classes named KLASS. */
classes = lookup_prefix_sym (state, file_symtabs, klass);
make_cleanup (VEC_cleanup (symbolp), &classes);
if (!VEC_empty (symbolp, classes))
{
/* Now locate a list of suitable methods named METHOD. */
TRY_CATCH (except, RETURN_MASK_ERROR)
{
find_method (state, file_symtabs, klass, method, classes,
symbols, minsyms);
}
/* If successful, we're done. If NOT_FOUND_ERROR
was not thrown, rethrow the exception that we did get. */
if (except.reason < 0 && except.error != NOT_FOUND_ERROR)
throw_exception (except);
}
}
/* We couldn't find a class, so we check the entire name as a symbol
instead. */
find_function_symbols (state, file_symtabs, lookup_name, symbols, minsyms);
do_cleanups (cleanup);
do_cleanups (cleanup);
}
/* Return all labels named NAME in FUNCTION_SYMBOLS. Return the