aboutsummaryrefslogtreecommitdiff
path: root/gdb/linespec.c
diff options
context:
space:
mode:
authorDoug Evans <dje@google.com>2013-03-11 18:24:59 +0000
committerDoug Evans <dje@google.com>2013-03-11 18:24:59 +0000
commitcc81e1c673ae438d57d5287ec64e2fd6e875377a (patch)
treebcd44e527d78f9cf98f121e7c9fb49a4b5022fda /gdb/linespec.c
parent39086a0e1346572fac07542ede2a1ef153308a2a (diff)
downloadgdb-cc81e1c673ae438d57d5287ec64e2fd6e875377a.zip
gdb-cc81e1c673ae438d57d5287ec64e2fd6e875377a.tar.gz
gdb-cc81e1c673ae438d57d5287ec64e2fd6e875377a.tar.bz2
* linespec.c (find_linespec_symbols): Call find_function_symbols
first, and then call lookup_prefix_sym/find_method.
Diffstat (limited to 'gdb/linespec.c')
-rw-r--r--gdb/linespec.c129
1 files changed, 71 insertions, 58 deletions
diff --git a/gdb/linespec.c b/gdb/linespec.c
index b1395e8..4fb49bb 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -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)
- {
- /* No C++ scope operator. Try Java. */
- scope_op = ".";
- p = find_toplevel_string (lookup_name, scope_op);
- }
+ /* 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) */
- last = NULL;
- while (p != NULL)
- {
- last = p;
- p = find_toplevel_string (p + strlen (scope_op), scope_op);
- }
+ find_function_symbols (state, file_symtabs, lookup_name,
+ symbols, minsyms);
- /* If no scope operator was found, lookup the name as a symbol. */
- if (last == NULL)
+ /* 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))
{
- find_function_symbols (state, file_symtabs, lookup_name,
- symbols, minsyms);
- do_cleanups (cleanup);
- return;
- }
+ char *klass, *method;
+ const char *last, *p, *scope_op;
+ VEC (symbolp) *classes;
- /* 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);
+ /* 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)
+ {
+ /* No C++ scope operator. Try Java. */
+ scope_op = ".";
+ p = find_toplevel_string (lookup_name, scope_op);
+ }
- /* 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)
+ last = NULL;
+ while (p != NULL)
{
- find_method (state, file_symtabs, klass, method, classes,
- symbols, minsyms);
+ last = p;
+ p = find_toplevel_string (p + strlen (scope_op), 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)
+ /* 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