summaryrefslogtreecommitdiff
path: root/gdb/linespec.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/linespec.c')
-rw-r--r--gdb/linespec.c525
1 files changed, 382 insertions, 143 deletions
diff --git a/gdb/linespec.c b/gdb/linespec.c
index b2233b92d8d..f1611b3e9b8 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -45,9 +45,6 @@
#include "stack.h"
#include "location.h"
-typedef struct symbol *symbolp;
-DEF_VEC_P (symbolp);
-
typedef struct type *typep;
DEF_VEC_P (typep);
@@ -61,10 +58,6 @@ struct address_entry
CORE_ADDR addr;
};
-typedef struct bound_minimal_symbol bound_minimal_symbol_d;
-
-DEF_VEC_O (bound_minimal_symbol_d);
-
/* A linespec. Elements of this structure are filled in by a parser
(either parse_linespec or some other function). The structure is
then converted into SALs by convert_linespec_to_sals. */
@@ -148,6 +141,9 @@ struct linespec_state
/* Are we building a linespec? */
int is_linespec;
+
+ /* !!keiths */
+ const struct decode_line_limits *limits;
};
/* This is a helper object that is used when collecting symbols into a
@@ -244,13 +240,17 @@ struct ls_parser
/* Is the entire linespec quote-enclosed? */
int is_quote_enclosed;
+ /* Did RESULT come from a cache? If so, don't free it when the
+ parser is deleted. */
+ int is_cached;
+
/* The state of the parse. */
struct linespec_state state;
#define PARSER_STATE(PPTR) (&(PPTR)->state)
/* The result of the parse. */
- struct linespec result;
-#define PARSER_RESULT(PPTR) (&(PPTR)->result)
+ struct linespec *result;
+#define PARSER_RESULT(PPTR) ((PPTR)->result)
};
typedef struct ls_parser linespec_parser;
@@ -274,7 +274,8 @@ static struct symtabs_and_lines decode_objc (struct linespec_state *self,
linespec_p ls,
const char *arg);
-static VEC (symtab_ptr) *symtabs_from_filename (const char *);
+static VEC (symtab_ptr) *symtabs_from_filename (const char *,
+ VEC (objfilep) *);
static VEC (symbolp) *find_label_symbols (struct linespec_state *self,
VEC (symbolp) *function_symbols,
@@ -302,7 +303,8 @@ static void add_all_symbol_names_from_pspace (struct collect_info *info,
struct program_space *pspace,
VEC (const_char_ptr) *names);
-static VEC (symtab_ptr) *collect_symtabs_from_filename (const char *file);
+static VEC (symtab_ptr) *collect_symtabs_from_filename (const char *file,
+ VEC (objfilep) *);
static void decode_digits_ordinary (struct linespec_state *self,
linespec_p ls,
@@ -323,6 +325,12 @@ static int compare_symbols (const void *a, const void *b);
static int compare_msymbols (const void *a, const void *b);
+static int classify_mtype (enum minimal_symbol_type t);
+
+#if MERGED_INTO_COMPARE_MSYMBOLS
+static int compare_msyms (const void *a, const void *b);
+#endif
+
/* Permitted quote characters for the parser. This is different from the
completer's quote characters to allow backward compatibility with the
previous parser. */
@@ -962,6 +970,50 @@ iterate_name_matcher (const char *name, void *d)
return 0; /* Skip this symbol. */
}
+#define DEBUG_ME 0
+#define USE_RESET_REASON 1
+
+static void
+do_iterate_over_matching_symtab (struct linespec_state *state,
+ struct objfile *objfile,
+ struct symbol_matcher_data *mdata,
+ const domain_enum domain,
+ symbol_found_callback_ftype callback,
+ void *data, int include_inline)
+{
+ struct compunit_symtab *cu;
+
+ if (objfile->sf)
+ objfile->sf->qf->expand_symtabs_matching (objfile, NULL,
+ iterate_name_matcher,
+ NULL, ALL_DOMAIN,
+ mdata);
+
+ ALL_OBJFILE_COMPUNITS (objfile, cu)
+ {
+ struct symtab *symtab = COMPUNIT_FILETABS (cu);
+
+ iterate_over_file_blocks (symtab, mdata->lookup_name, domain,
+ callback, data);
+
+ if (include_inline)
+ {
+ struct symbol_and_data_callback cad = { callback, data };
+ struct block *block;
+ int i;
+
+ for (i = FIRST_LOCAL_BLOCK;
+ i < BLOCKVECTOR_NBLOCKS (SYMTAB_BLOCKVECTOR (symtab));
+ i++)
+ {
+ block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i);
+ state->language->la_iterate_over_symbols
+ (block, mdata->lookup_name, domain, iterate_inline_only, &cad);
+ }
+ }
+ }
+}
+
/* A helper that walks over all matching symtabs in all objfiles and
calls CALLBACK for each symbol matching NAME. If SEARCH_PSPACE is
not NULL, then the search is restricted to just that program
@@ -996,39 +1048,38 @@ iterate_over_all_matching_symtabs (struct linespec_state *state,
set_current_program_space (pspace);
- ALL_OBJFILES (objfile)
- {
- struct compunit_symtab *cu;
-
- if (objfile->sf)
- objfile->sf->qf->expand_symtabs_matching (objfile, NULL,
- iterate_name_matcher,
- NULL, ALL_DOMAIN,
- &matcher_data);
+#if USE_RESET_REASON
+ if (state->limits != NULL && state->limits->objfiles != NULL)
+ {
+ int i;
- ALL_OBJFILE_COMPUNITS (objfile, cu)
+ for (i = 0;
+ VEC_iterate (objfilep, state->limits->objfiles, i, objfile);
+ ++i)
+ {
+#if DEBUG_ME
+ printf ("(limit) looking for \"%s\" in objfile %s\n", name,
+ objfile->original_name);
+#endif
+ do_iterate_over_matching_symtab (state, objfile, &matcher_data,
+ domain, callback, data,
+ include_inline);
+ }
+ }
+ else
+#endif
+ {
+ ALL_OBJFILES (objfile)
{
- struct symtab *symtab = COMPUNIT_FILETABS (cu);
-
- iterate_over_file_blocks (symtab, name, domain, callback, data);
-
- if (include_inline)
- {
- struct symbol_and_data_callback cad = { callback, data };
- struct block *block;
- int i;
-
- for (i = FIRST_LOCAL_BLOCK;
- i < BLOCKVECTOR_NBLOCKS (SYMTAB_BLOCKVECTOR (symtab));
- i++)
- {
- block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i);
- state->language->la_iterate_over_symbols
- (block, name, domain, iterate_inline_only, &cad);
- }
- }
+#if DEBUG_ME
+ printf ("(all) looking for \"%s\" in objfile %s\n", name,
+ objfile->original_name);
+#endif
+ do_iterate_over_matching_symtab (state, objfile, &matcher_data,
+ domain, callback, data,
+ include_inline);
}
- }
+ }
}
}
@@ -1833,6 +1884,7 @@ create_sals_line_offset (struct linespec_state *self,
&& VEC_index (symtab_ptr, ls->file_symtabs, 0) == NULL)
{
const char *fullname;
+ VEC (objfilep) *objfiles = NULL;
set_current_program_space (self->program_space);
@@ -1842,7 +1894,9 @@ create_sals_line_offset (struct linespec_state *self,
fullname = symtab_to_fullname (self->default_symtab);
VEC_pop (symtab_ptr, ls->file_symtabs);
VEC_free (symtab_ptr, ls->file_symtabs);
- ls->file_symtabs = collect_symtabs_from_filename (fullname);
+ if (self->limits != NULL)
+ objfiles = self->limits->objfiles;
+ ls->file_symtabs = collect_symtabs_from_filename (fullname, objfiles);
use_default = 1;
}
@@ -2005,7 +2059,7 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
else if (ls->function_symbols != NULL || ls->minimal_symbols != NULL)
{
/* We have just a bunch of functions and/or methods. */
- int i;
+ int i, classification;
struct symtab_and_line sal;
struct symbol *sym;
bound_minimal_symbol_d *elem;
@@ -2032,16 +2086,26 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
if (ls->minimal_symbols != NULL)
{
- /* Sort minimal symbols by program space, too. */
+ /* Sort minimal symbols by classification and program space. */
qsort (VEC_address (bound_minimal_symbol_d, ls->minimal_symbols),
VEC_length (bound_minimal_symbol_d, ls->minimal_symbols),
sizeof (bound_minimal_symbol_d), compare_msymbols);
+ /* Now the minsyms are in classification order with minsyms
+ of the same program space all adjacent to one another. So,
+ we walk over them and process just the minsyms with the same
+ classification as the very first minsym in the list. */
+ elem = VEC_index (bound_minimal_symbol_d, ls->minimal_symbols, 0);
+ classification = classify_mtype (MSYMBOL_TYPE (elem->minsym));
+
for (i = 0;
VEC_iterate (bound_minimal_symbol_d, ls->minimal_symbols,
i, elem);
++i)
{
+ if (classify_mtype (MSYMBOL_TYPE (elem->minsym))
+ != classification)
+ break;
pspace = elem->objfile->pspace;
set_current_program_space (pspace);
minsym_found (state, elem->objfile, elem->minsym, &sals);
@@ -2088,31 +2152,55 @@ convert_explicit_location_to_sals (struct linespec_state *self,
{
VEC (symbolp) *symbols, *labels;
VEC (bound_minimal_symbol_d) *minimal_symbols;
+ VEC (symtab_ptr) *symtabs = NULL;
if (explicit_loc->source_filename != NULL)
{
TRY
{
- result->file_symtabs
- = symtabs_from_filename (explicit_loc->source_filename);
+ VEC (objfilep) *objfiles = NULL;
+
+ if (self->limits != NULL)
+ objfiles = self->limits->objfiles;
+ symtabs
+ = symtabs_from_filename (explicit_loc->source_filename, objfiles);
}
CATCH (except, RETURN_MASK_ERROR)
{
source_file_not_found_error (explicit_loc->source_filename);
}
END_CATCH
- result->explicit_loc.source_filename
- = xstrdup (explicit_loc->source_filename);
+
+ /* !!keiths: Really what we want to know is if we are doing this
+ incrementally, i.e., there are limits. LIMITS is just about
+ always non-NULL. */
+#define HAS_LIMIT(X) ((X)->limits != NULL && (X)->limits->objfiles != NULL)
+ if (HAS_LIMIT (self))
+ {
+ int ix;
+ struct symtab *elt;
+
+ for (ix = 0; VEC_iterate (symtab_ptr, symtabs, ix, elt); ++ix)
+ VEC_safe_push (symtab_ptr, result->file_symtabs, elt);
+ }
+ else
+ {
+ result->file_symtabs = symtabs;
+ result->explicit_loc.source_filename
+ = xstrdup (explicit_loc->source_filename);
+ }
}
else
{
/* A NULL entry means to use the default symtab. */
- VEC_safe_push (symtab_ptr, result->file_symtabs, NULL);
+ VEC_safe_push (symtab_ptr, symtabs, NULL);
+ if (!HAS_LIMIT (self))
+ result->file_symtabs = symtabs;
}
if (explicit_loc->function_name != NULL)
{
- find_linespec_symbols (self, result->file_symtabs,
+ find_linespec_symbols (self, symtabs,
explicit_loc->function_name, &symbols,
&minimal_symbols);
@@ -2120,28 +2208,62 @@ convert_explicit_location_to_sals (struct linespec_state *self,
symbol_not_found_error (explicit_loc->function_name,
result->explicit_loc.source_filename);
- result->explicit_loc.function_name
- = xstrdup (explicit_loc->function_name);
- result->function_symbols = symbols;
- result->minimal_symbols = minimal_symbols;
+ if (HAS_LIMIT (self))
+ {
+ int ix;
+ bound_minimal_symbol_d *ms_elt;
+ struct symbol *s_elt;
+
+ /* !!keiths: Ick. VEC_merge? */
+ for (ix = 0; VEC_iterate (symbolp, symbols, ix, s_elt); ++ix)
+ VEC_safe_push (symbolp, result->function_symbols, s_elt);
+ for (ix = 0; VEC_iterate (bound_minimal_symbol_d,
+ minimal_symbols, ix, ms_elt); ++ix)
+ {
+ VEC_safe_push (bound_minimal_symbol_d, result->minimal_symbols,
+ ms_elt);
+ }
+ }
+ else
+ {
+ result->explicit_loc.function_name
+ = xstrdup (explicit_loc->function_name);
+ result->function_symbols = symbols;
+ result->minimal_symbols = minimal_symbols;
+ }
}
if (explicit_loc->label_name != NULL)
{
- symbols = NULL;
- labels = find_label_symbols (self, result->function_symbols,
- &symbols, explicit_loc->label_name);
+ VEC (symbolp) *label_symbols = NULL;
+
+ labels = find_label_symbols (self, symbols,
+ &label_symbols, explicit_loc->label_name);
if (labels == NULL)
undefined_label_error (result->explicit_loc.function_name,
explicit_loc->label_name);
- result->explicit_loc.label_name = xstrdup (explicit_loc->label_name);
- result->labels.label_symbols = labels;
- result->labels.function_symbols = symbols;
+ if (HAS_LIMIT (self))
+ {
+ int ix;
+ struct symbol *elt;
+
+ for (ix = 0; VEC_iterate (symbolp, labels, ix, elt); ++ix)
+ VEC_safe_push (symbolp, result->labels.label_symbols, elt);
+ for (ix = 0; VEC_iterate (symbolp, label_symbols, ix, elt); ++ix)
+ VEC_safe_push (symbolp, result->labels.function_symbols, elt);
+ }
+ else
+ {
+ result->explicit_loc.label_name = xstrdup (explicit_loc->label_name);
+ result->labels.label_symbols = labels;
+ result->labels.function_symbols = label_symbols;
+ }
}
- if (explicit_loc->line_offset.sign != LINE_OFFSET_UNKNOWN)
+ if (explicit_loc->line_offset.sign != LINE_OFFSET_UNKNOWN
+ && !HAS_LIMIT (self))
result->explicit_loc.line_offset = explicit_loc->line_offset;
return convert_linespec_to_sals (self, result);
@@ -2284,8 +2406,15 @@ parse_linespec (linespec_parser *parser, const char *arg)
/* Check if the input is a filename. */
TRY
{
+ VEC (objfilep) *objfiles = NULL;
+
+ if (PARSER_STATE (parser)->limits != NULL)
+ objfiles = PARSER_STATE (parser)->limits->objfiles;
+
PARSER_RESULT (parser)->file_symtabs
- = symtabs_from_filename (user_filename);
+ = symtabs_from_filename (user_filename, objfiles);
+ /* !!keiths: From here on out, if file_symtabs does not contain
+ NULL, objfile limits are ALREADY taken into consideration. */
}
CATCH (ex, RETURN_MASK_ERROR)
{
@@ -2366,19 +2495,19 @@ parse_linespec (linespec_parser *parser, const char *arg)
static void
linespec_state_constructor (struct linespec_state *self,
- int flags, const struct language_defn *language,
- struct symtab *default_symtab,
- int default_line,
- struct linespec_result *canonical)
+ const struct language_defn *language,
+ struct linespec_result *canonical,
+ const struct decode_line_options *options)
{
memset (self, 0, sizeof (*self));
self->language = language;
- self->funfirstline = (flags & DECODE_LINE_FUNFIRSTLINE) ? 1 : 0;
- self->list_mode = (flags & DECODE_LINE_LIST_MODE) ? 1 : 0;
- self->default_symtab = default_symtab;
- self->default_line = default_line;
+ self->funfirstline = (options->flags & DECODE_LINE_FUNFIRSTLINE) ? 1 : 0;
+ self->list_mode = (options->flags & DECODE_LINE_LIST_MODE) ? 1 : 0;
+ self->default_symtab = options->default_symtab;
+ self->default_line = options->default_line;
self->canonical = canonical;
self->program_space = current_program_space;
+ self->limits = options->limits;
self->addr_set = htab_create_alloc (10, hash_address_entry, eq_address_entry,
xfree, xcalloc, xfree);
self->is_linespec = 0;
@@ -2388,17 +2517,24 @@ linespec_state_constructor (struct linespec_state *self,
static void
linespec_parser_new (linespec_parser *parser,
- int flags, const struct language_defn *language,
- struct symtab *default_symtab,
- int default_line,
- struct linespec_result *canonical)
+ const struct language_defn *language,
+ struct linespec_result *canonical,
+ const struct decode_line_options *options)
{
memset (parser, 0, sizeof (linespec_parser));
parser->lexer.current.type = LSTOKEN_CONSUMED;
- memset (PARSER_RESULT (parser), 0, sizeof (struct linespec));
- PARSER_EXPLICIT (parser)->line_offset.sign = LINE_OFFSET_UNKNOWN;
- linespec_state_constructor (PARSER_STATE (parser), flags, language,
- default_symtab, default_line, canonical);
+ if (options->cache == NULL)
+ {
+ PARSER_RESULT (parser) = XCNEW (struct linespec);
+ PARSER_EXPLICIT (parser)->line_offset.sign = LINE_OFFSET_UNKNOWN;
+ }
+ else
+ {
+ PARSER_RESULT (parser) = options->cache;
+ parser->is_cached = 1;
+ }
+ linespec_state_constructor (PARSER_STATE (parser), language,
+ canonical, options);
}
/* A destructor for linespec_state. */
@@ -2409,32 +2545,48 @@ linespec_state_destructor (struct linespec_state *self)
htab_delete (self->addr_set);
}
-/* Delete a linespec parser. */
-
static void
-linespec_parser_delete (void *arg)
+free_linespec_result (linespec_p result)
{
- linespec_parser *parser = (linespec_parser *) arg;
+ if (result == NULL)
+ return;
- xfree (PARSER_EXPLICIT (parser)->source_filename);
- xfree (PARSER_EXPLICIT (parser)->label_name);
- xfree (PARSER_EXPLICIT (parser)->function_name);
+ xfree (result->explicit_loc.source_filename);
+ xfree (result->explicit_loc.label_name);
+ xfree (result->explicit_loc.function_name);
- if (PARSER_RESULT (parser)->file_symtabs != NULL)
- VEC_free (symtab_ptr, PARSER_RESULT (parser)->file_symtabs);
+ if (result->file_symtabs != NULL)
+ VEC_free (symtab_ptr, result->file_symtabs);
- if (PARSER_RESULT (parser)->function_symbols != NULL)
- VEC_free (symbolp, PARSER_RESULT (parser)->function_symbols);
+ if (result->function_symbols != NULL)
+ VEC_free (symbolp, result->function_symbols);
- if (PARSER_RESULT (parser)->minimal_symbols != NULL)
- VEC_free (bound_minimal_symbol_d, PARSER_RESULT (parser)->minimal_symbols);
+ if (result->minimal_symbols != NULL)
+ VEC_free (bound_minimal_symbol_d, result->minimal_symbols);
- if (PARSER_RESULT (parser)->labels.label_symbols != NULL)
- VEC_free (symbolp, PARSER_RESULT (parser)->labels.label_symbols);
+ if (result->labels.label_symbols != NULL)
+ VEC_free (symbolp, result->labels.label_symbols);
+
+ if (result->labels.function_symbols != NULL)
+ VEC_free (symbolp, result->labels.function_symbols);
+}
- if (PARSER_RESULT (parser)->labels.function_symbols != NULL)
- VEC_free (symbolp, PARSER_RESULT (parser)->labels.function_symbols);
+void
+invalidate_linespec_cache (struct linespec **p)
+{
+ free_linespec_result (*p);
+ *p = NULL;
+}
+/* Delete a linespec parser. */
+
+static void
+linespec_parser_delete (void *arg)
+{
+ linespec_parser *parser = (linespec_parser *) arg;
+
+ if (!parser->is_cached)
+ free_linespec_result (PARSER_RESULT (parser));
linespec_state_destructor (PARSER_STATE (parser));
}
@@ -2447,11 +2599,13 @@ linespec_lex_to_end (char **stringp)
struct cleanup *cleanup;
linespec_token token;
const char *orig;
+ struct decode_line_options opts;
if (stringp == NULL || *stringp == NULL)
return;
- linespec_parser_new (&parser, 0, current_language, NULL, 0, NULL);
+ init_decode_line_options (&opts);
+ linespec_parser_new (&parser, current_language, NULL, &opts);
cleanup = make_cleanup (linespec_parser_delete, &parser);
parser.lexer.saved_arg = *stringp;
PARSER_STREAM (&parser) = orig = *stringp;
@@ -2526,38 +2680,56 @@ event_location_to_sals (linespec_parser *parser,
return result;
}
+/* Initialize a decode_line_options structure.
+ OPTS->FLAGS will be initialized to DECODE_LINE_FUNFIRSTLINE. */
+
+void
+init_decode_line_options (struct decode_line_options *opts)
+{
+ memset (opts, 0, sizeof (struct decode_line_options));
+ opts->flags = DECODE_LINE_FUNFIRSTLINE;
+}
+
/* See linespec.h. */
void
-decode_line_full (const struct event_location *location, int flags,
- struct symtab *default_symtab,
- int default_line, struct linespec_result *canonical,
- const char *select_mode,
- const char *filter)
+decode_line_full (const struct event_location *location,
+ struct linespec_result *canonical,
+ const struct decode_line_options *options)
{
struct symtabs_and_lines result;
struct cleanup *cleanups;
VEC (const_char_ptr) *filters = NULL;
linespec_parser parser;
struct linespec_state *state;
+ const char *copy, *orig;
+ const char *select_mode = options->select_mode;
gdb_assert (canonical != NULL);
/* The filter only makes sense for 'all'. */
- gdb_assert (filter == NULL || select_mode == multiple_symbols_all);
+ gdb_assert (options->filter == NULL || select_mode == multiple_symbols_all);
gdb_assert (select_mode == NULL
|| select_mode == multiple_symbols_all
|| select_mode == multiple_symbols_ask
|| select_mode == multiple_symbols_cancel);
- gdb_assert ((flags & DECODE_LINE_LIST_MODE) == 0);
+ gdb_assert ((options->flags & DECODE_LINE_LIST_MODE) == 0);
- linespec_parser_new (&parser, flags, current_language, default_symtab,
- default_line, canonical);
+#if DEBUG_ME
+ if (options->cache != NULL)
+ printf ("*** got linespec cache ***\n");
+#endif
+ linespec_parser_new (&parser, current_language, canonical, options);
cleanups = make_cleanup (linespec_parser_delete, &parser);
save_current_program_space ();
result = event_location_to_sals (&parser, location);
state = PARSER_STATE (&parser);
+ if (options->limits != NULL && result.nelts == 0)
+ {
+ throw_error (NOT_FOUND_ERROR, _("didn't find function under limits"));
+ }
+
gdb_assert (result.nelts == 1 || canonical->pre_expanded);
canonical->pre_expanded = 1;
@@ -2584,10 +2756,10 @@ decode_line_full (const struct event_location *location, int flags,
if (select_mode == multiple_symbols_all)
{
- if (filter != NULL)
+ if (options->filter != NULL)
{
make_cleanup (VEC_cleanup (const_char_ptr), &filters);
- VEC_safe_push (const_char_ptr, filters, filter);
+ VEC_safe_push (const_char_ptr, filters, options->filter);
filter_results (state, &result, filters);
}
else
@@ -2596,22 +2768,31 @@ decode_line_full (const struct event_location *location, int flags,
else
decode_line_2 (state, &result, select_mode);
+ if (options->flags & DECODE_LINE_CREATE_CACHE)
+ {
+#if DEBUG_ME
+ printf ("*** creating linespec cache ***\n");
+#endif
+ canonical->cache = PARSER_RESULT (&parser);
+ /* !!keiths: Hmm. Pretty sure we don't want to be free'ing
+ this when the cleanup is called... */
+ PARSER_RESULT (&parser) = NULL;
+ }
+
do_cleanups (cleanups);
}
/* See linespec.h. */
struct symtabs_and_lines
-decode_line_1 (const struct event_location *location, int flags,
- struct symtab *default_symtab,
- int default_line)
+decode_line_1 (const struct event_location *location,
+ const struct decode_line_options *options)
{
struct symtabs_and_lines result;
linespec_parser parser;
struct cleanup *cleanups;
- linespec_parser_new (&parser, flags, current_language, default_symtab,
- default_line, NULL);
+ linespec_parser_new (&parser, current_language, NULL, options);
cleanups = make_cleanup (linespec_parser_delete, &parser);
save_current_program_space ();
@@ -2630,6 +2811,7 @@ decode_line_with_current_source (char *string, int flags)
struct symtab_and_line cursal;
struct event_location *location;
struct cleanup *cleanup;
+ struct decode_line_options options;
if (string == 0)
error (_("Empty line specification."));
@@ -2640,8 +2822,11 @@ decode_line_with_current_source (char *string, int flags)
location = string_to_event_location (&string, current_language);
cleanup = make_cleanup_delete_event_location (location);
- sals = decode_line_1 (location, flags,
- cursal.symtab, cursal.line);
+ init_decode_line_options (&options);
+ options.flags = flags;
+ options.default_symtab = cursal.symtab;
+ options.default_line = cursal.line;
+ sals = decode_line_1 (location, &options);
if (*string)
error (_("Junk at end of line specification: %s"), string);
@@ -2658,18 +2843,23 @@ decode_line_with_last_displayed (char *string, int flags)
struct symtabs_and_lines sals;
struct event_location *location;
struct cleanup *cleanup;
+ struct decode_line_options options;
if (string == 0)
error (_("Empty line specification."));
location = string_to_event_location (&string, current_language);
cleanup = make_cleanup_delete_event_location (location);
+ init_decode_line_options (&options);
+ options.flags = flags;
if (last_displayed_sal_is_valid ())
- sals = decode_line_1 (location, flags,
- get_last_displayed_symtab (),
- get_last_displayed_line ());
+ {
+ options.default_symtab = get_last_displayed_symtab ();
+ options.default_line = get_last_displayed_line ();
+ sals = decode_line_1 (location, &options);
+ }
else
- sals = decode_line_1 (location, flags, (struct symtab *) NULL, 0);
+ sals = decode_line_1 (location, &options);
if (*string)
error (_("Junk at end of line specification: %s"), string);
@@ -2831,6 +3021,15 @@ collect_one_symbol (struct symbol *sym, void *d)
{
*slot = sym;
VEC_safe_push (symbolp, collector->symbols, sym);
+#if DEBUG_ME
+ {
+ struct objfile *_objfile = SYMBOL_OBJFILE_OWNED (sym) ? symbol_objfile (sym) : NULL;
+
+ printf ("(one) found symbol %s in objfile %s\n",
+ SYMBOL_LINKAGE_NAME (sym),
+ _objfile ? _objfile->original_name : "arch");
+ }
+#endif
}
return 1; /* Continue iterating. */
@@ -2925,7 +3124,15 @@ compare_msymbols (const void *a, const void *b)
const struct bound_minimal_symbol *sb
= (const struct bound_minimal_symbol *) b;
uintptr_t uia, uib;
+ int ca, cb;
+ /* !!keiths: First compare by classification... */
+ ca = classify_mtype (MSYMBOL_TYPE (sa->minsym));
+ cb = classify_mtype (MSYMBOL_TYPE (sb->minsym));
+ if (ca - cb != 0)
+ return ca - cb;
+
+ /* !!keiths; Now compare pspaces. */
uia = (uintptr_t) sa->objfile->pspace;
uib = (uintptr_t) sa->objfile->pspace;
@@ -3120,7 +3327,7 @@ add_symtabs_to_list (struct symtab *symtab, void *d)
/* Given a file name, return a VEC of all matching symtabs. */
static VEC (symtab_ptr) *
-collect_symtabs_from_filename (const char *file)
+collect_symtabs_from_filename (const char *file, VEC (objfilep) *objfiles)
{
struct symtab_collector collector;
struct cleanup *cleanups;
@@ -3138,7 +3345,7 @@ collect_symtabs_from_filename (const char *file)
continue;
set_current_program_space (pspace);
- iterate_over_symtabs (file, add_symtabs_to_list, &collector);
+ iterate_over_symtabs (file, objfiles, add_symtabs_to_list, &collector);
}
do_cleanups (cleanups);
@@ -3148,11 +3355,11 @@ collect_symtabs_from_filename (const char *file)
/* Return all the symtabs associated to the FILENAME. */
static VEC (symtab_ptr) *
-symtabs_from_filename (const char *filename)
+symtabs_from_filename (const char *filename, VEC (objfilep) *objfiles)
{
VEC (symtab_ptr) *result;
- result = collect_symtabs_from_filename (filename);
+ result = collect_symtabs_from_filename (filename, objfiles);
if (VEC_empty (symtab_ptr, result))
{
@@ -3532,7 +3739,18 @@ collect_symbols (struct symbol *sym, void *data)
/* In list mode, add all matching symbols, regardless of class.
This allows the user to type "list a_global_variable". */
if (SYMBOL_CLASS (sym) == LOC_BLOCK || info->state->list_mode)
- VEC_safe_push (symbolp, info->result.symbols, sym);
+ {
+ VEC_safe_push (symbolp, info->result.symbols, sym);
+#if DEBUG_ME
+ {
+ struct objfile *_objfile = SYMBOL_OBJFILE_OWNED (sym) ? symbol_objfile (sym) : NULL;
+
+ printf ("found symbol %s in objfile %s\n",
+ SYMBOL_LINKAGE_NAME (sym),
+ _objfile ? _objfile->original_name : "arch");
+ }
+#endif
+ }
return 1; /* Continue iterating. */
}
@@ -3630,6 +3848,7 @@ classify_mtype (enum minimal_symbol_type t)
}
}
+#if MERGED_INTO_COMPARE_MSYMBOLS
/* Callback for qsort that sorts symbols by priority. */
static int
@@ -3642,6 +3861,7 @@ compare_msyms (const void *a, const void *b)
return classify_mtype (ta) - classify_mtype (tb);
}
+#endif
/* Callback for iterate_over_minimal_symbols that adds the symbol to
the result. */
@@ -3697,6 +3917,10 @@ add_minsym (struct minimal_symbol *minsym, void *d)
}
VEC_safe_push (bound_minimal_symbol_d, info->msyms, &mo);
+#if DEBUG_ME
+ printf ("found minsym %s in objfile %s\n",
+ MSYMBOL_LINKAGE_NAME (minsym), mo.objfile->original_name);
+#endif
}
/* Search for minimal symbols called NAME. If SEARCH_PSPACE
@@ -3736,11 +3960,30 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
set_current_program_space (pspace);
- ALL_OBJFILES (objfile)
- {
- local.objfile = objfile;
- iterate_over_minimal_symbols (objfile, name, add_minsym, &local);
- }
+#if USE_RESET_REASON
+ if (info->state->limits != NULL
+ && info->state->limits->objfiles != NULL)
+ {
+ int i;
+
+ for (i = 0;
+ VEC_iterate (objfilep, info->state->limits->objfiles, i,
+ objfile); ++i)
+ {
+ local.objfile = objfile;
+ iterate_over_minimal_symbols (objfile, name, add_minsym,
+ &local);
+ }
+ }
+ else
+#endif
+ {
+ ALL_OBJFILES (objfile)
+ {
+ local.objfile = objfile;
+ iterate_over_minimal_symbols (objfile, name, add_minsym, &local);
+ }
+ }
}
}
else
@@ -3756,28 +3999,17 @@ search_minsyms_for_name (struct collect_info *info, const char *name,
if (!VEC_empty (bound_minimal_symbol_d, local.msyms))
{
- int classification;
int ix;
bound_minimal_symbol_d *item;
- qsort (VEC_address (bound_minimal_symbol_d, local.msyms),
- VEC_length (bound_minimal_symbol_d, local.msyms),
- sizeof (bound_minimal_symbol_d),
- compare_msyms);
-
- /* Now the minsyms are in classification order. So, we walk
- over them and process just the minsyms with the same
- classification as the very first minsym in the list. */
- item = VEC_index (bound_minimal_symbol_d, local.msyms, 0);
- classification = classify_mtype (MSYMBOL_TYPE (item->minsym));
-
+ /* !!keiths: This pushes ALL minsyms up. This is a small
+ internal API change, but is needed in order to cache the
+ linespec result. Lower priority minsym classes will be
+ filtered when the SaLs are actually created. */
for (ix = 0;
VEC_iterate (bound_minimal_symbol_d, local.msyms, ix, item);
++ix)
{
- if (classify_mtype (MSYMBOL_TYPE (item->minsym)) != classification)
- break;
-
VEC_safe_push (bound_minimal_symbol_d,
info->result.minimal_symbols, item);
}
@@ -3896,6 +4128,7 @@ destroy_linespec_result (struct linespec_result *ls)
xfree (lsal->sals.sals);
}
VEC_free (linespec_sals, ls->sals);
+ free_linespec_result (ls->cache);
}
/* Cleanup function for a linespec_result. */
@@ -3921,3 +4154,9 @@ get_gdb_linespec_parser_quote_characters (void)
{
return linespec_quote_characters;
}
+
+void
+init_decode_line_limits (struct decode_line_limits *limits)
+{
+ memset (limits, 0, sizeof (struct decode_line_limits));
+}