diff options
author | Doug Evans <dje@google.com> | 2013-03-11 18:24:59 +0000 |
---|---|---|
committer | Doug Evans <dje@google.com> | 2013-03-11 18:24:59 +0000 |
commit | cc81e1c673ae438d57d5287ec64e2fd6e875377a (patch) | |
tree | bcd44e527d78f9cf98f121e7c9fb49a4b5022fda /gdb | |
parent | 39086a0e1346572fac07542ede2a1ef153308a2a (diff) | |
download | gdb-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')
-rw-r--r-- | gdb/ChangeLog | 6 | ||||
-rw-r--r-- | gdb/linespec.c | 129 |
2 files changed, 77 insertions, 58 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 3334f62..9084fa0 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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 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 |