/* Parser for linespec for the GNU debugger, GDB.
- Copyright (C) 1986-2015 Free Software Foundation, Inc.
+ Copyright (C) 1986-2017 Free Software Foundation, Inc.
This file is part of GDB.
#include "ada-lang.h"
#include "stack.h"
#include "location.h"
+#include "common/function-view.h"
typedef struct symbol *symbolp;
DEF_VEC_P (symbolp);
/* The program space as seen when the module was entered. */
struct program_space *program_space;
+ /* If not NULL, the search is restricted to just this program
+ space. */
+ struct program_space *search_pspace;
+
/* The default symtab to use, if no other symtab is specified. */
struct symtab *default_symtab;
VEC (symbolp) *symbols;
VEC (bound_minimal_symbol_d) *minimal_symbols;
} result;
+
+ /* Possibly add a symbol to the results. */
+ bool add_symbol (symbol *sym);
};
+bool
+collect_info::add_symbol (symbol *sym)
+{
+ /* 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 || this->state->list_mode)
+ VEC_safe_push (symbolp, this->result.symbols, sym);
+
+ /* Continue iterating. */
+ return true;
+}
+
/* Token types */
enum ls_token_type
/* Prototypes for local functions. */
-static void iterate_over_file_blocks (struct symtab *symtab,
- const char *name, domain_enum domain,
- symbol_found_callback_ftype *callback,
- void *data);
+static void iterate_over_file_blocks
+ (struct symtab *symtab, const char *name, domain_enum domain,
+ gdb::function_view<symbol_found_callback_ftype> callback);
static void initialize_defaults (struct symtab **default_symtab,
int *default_line);
linespec_p ls,
const char *arg);
-static VEC (symtab_ptr) *symtabs_from_filename (const char *);
+static VEC (symtab_ptr) *symtabs_from_filename (const char *,
+ struct program_space *pspace);
static VEC (symbolp) *find_label_symbols (struct linespec_state *self,
VEC (symbolp) *function_symbols,
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,
+ struct program_space *pspace);
static void decode_digits_ordinary (struct linespec_state *self,
linespec_p ls,
&& (PARSER_STREAM (parser) - start) > 8
/* strlen ("operator") */)
{
- char *p = strstr (start, "operator");
+ const char *p = strstr (start, "operator");
if (p != NULL && is_operator_name (p))
{
struct symtab_and_line *sal)
{
++sals->nelts;
- sals->sals = xrealloc (sals->sals, sals->nelts * sizeof (sals->sals[0]));
+ sals->sals = XRESIZEVEC (struct symtab_and_line, sals->sals, sals->nelts);
sals->sals[sals->nelts - 1] = *sal;
}
{
struct linespec_canonical_name *canonical;
- self->canonical_names = xrealloc (self->canonical_names,
- (sals->nelts
- * sizeof (*self->canonical_names)));
+ self->canonical_names = XRESIZEVEC (struct linespec_canonical_name,
+ self->canonical_names, sals->nelts);
canonical = &self->canonical_names[sals->nelts - 1];
if (!literal_canonical && sal->symtab)
{
- const char *fullname = symtab_to_fullname (sal->symtab);
+ symtab_to_fullname (sal->symtab);
/* Note that the filter doesn't have to be a valid linespec
input. We only apply the ":LINE" treatment to Ada for
static hashval_t
hash_address_entry (const void *p)
{
- const struct address_entry *aep = p;
+ const struct address_entry *aep = (const struct address_entry *) p;
hashval_t hash;
hash = iterative_hash_object (aep->pspace, 0);
static int
eq_address_entry (const void *a, const void *b)
{
- const struct address_entry *aea = a;
- const struct address_entry *aeb = b;
+ const struct address_entry *aea = (const struct address_entry *) a;
+ const struct address_entry *aeb = (const struct address_entry *) b;
return aea->pspace == aeb->pspace && aea->addr == aeb->addr;
}
return 1;
}
-/* A callback function and the additional data to call it with. */
-
-struct symbol_and_data_callback
-{
- /* The callback to use. */
- symbol_found_callback_ftype *callback;
-
- /* Data to be passed to the callback. */
- void *data;
-};
-
-/* A helper for iterate_over_all_matching_symtabs that is used to
- restrict calls to another callback to symbols representing inline
- symbols only. */
-
-static int
-iterate_inline_only (struct symbol *sym, void *d)
-{
- if (SYMBOL_INLINED (sym))
- {
- struct symbol_and_data_callback *cad = d;
-
- return cad->callback (sym, cad->data);
- }
- return 1; /* Continue iterating. */
-}
-
-/* Some data for the expand_symtabs_matching callback. */
-
-struct symbol_matcher_data
-{
- /* The lookup name against which symbol name should be compared. */
- const char *lookup_name;
-
- /* The routine to be used for comparison. */
- symbol_name_cmp_ftype symbol_name_cmp;
-};
-
-/* A helper for iterate_over_all_matching_symtabs that is passed as a
- callback to the expand_symtabs_matching method. */
-
-static int
-iterate_name_matcher (const char *name, void *d)
-{
- const struct symbol_matcher_data *data = d;
-
- if (data->symbol_name_cmp (name, data->lookup_name) == 0)
- return 1; /* Expand this symbol's symbol table. */
- return 0; /* Skip this symbol. */
-}
-
/* 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
- space. If INCLUDE_INLINE is nonzero then symbols representing
+ space. If INCLUDE_INLINE is true then symbols representing
inlined instances of functions will be included in the result. */
static void
-iterate_over_all_matching_symtabs (struct linespec_state *state,
- const char *name,
- const domain_enum domain,
- symbol_found_callback_ftype *callback,
- void *data,
- struct program_space *search_pspace,
- int include_inline)
+iterate_over_all_matching_symtabs
+ (struct linespec_state *state, const char *name, const domain_enum domain,
+ struct program_space *search_pspace, bool include_inline,
+ gdb::function_view<symbol_found_callback_ftype> callback)
{
struct objfile *objfile;
struct program_space *pspace;
- struct symbol_matcher_data matcher_data;
- matcher_data.lookup_name = name;
- matcher_data.symbol_name_cmp =
- state->language->la_get_symbol_name_cmp != NULL
- ? state->language->la_get_symbol_name_cmp (name)
- : strcmp_iw;
+ /* The routine to be used for comparison. */
+ symbol_name_cmp_ftype symbol_name_cmp
+ = (state->language->la_get_symbol_name_cmp != NULL
+ ? state->language->la_get_symbol_name_cmp (name)
+ : strcmp_iw);
ALL_PSPACES (pspace)
{
struct compunit_symtab *cu;
if (objfile->sf)
- objfile->sf->qf->expand_symtabs_matching (objfile, NULL,
- iterate_name_matcher,
- NULL, ALL_DOMAIN,
- &matcher_data);
+ objfile->sf->qf->expand_symtabs_matching
+ (objfile,
+ NULL,
+ [&] (const char *symbol_name)
+ {
+ return symbol_name_cmp (symbol_name, name) == 0;
+ },
+ NULL,
+ ALL_DOMAIN);
ALL_OBJFILE_COMPUNITS (objfile, cu)
{
struct symtab *symtab = COMPUNIT_FILETABS (cu);
- iterate_over_file_blocks (symtab, name, domain, callback, data);
+ iterate_over_file_blocks (symtab, name, domain, callback);
if (include_inline)
{
- struct symbol_and_data_callback cad = { callback, data };
struct block *block;
int i;
{
block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i);
state->language->la_iterate_over_symbols
- (block, name, domain, iterate_inline_only, &cad);
+ (block, name, domain, [&] (symbol *sym)
+ {
+ /* Restrict calls to CALLBACK to symbols
+ representing inline symbols only. */
+ if (SYMBOL_INLINED (sym))
+ return callback (sym);
+ return true;
+ });
}
}
}
/* Iterate over static and global blocks. */
static void
-iterate_over_file_blocks (struct symtab *symtab,
- const char *name, domain_enum domain,
- symbol_found_callback_ftype *callback, void *data)
+iterate_over_file_blocks
+ (struct symtab *symtab, const char *name, domain_enum domain,
+ gdb::function_view<symbol_found_callback_ftype> callback)
{
struct block *block;
for (block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), STATIC_BLOCK);
block != NULL;
block = BLOCK_SUPERBLOCK (block))
- LA_ITERATE_OVER_SYMBOLS (block, name, domain, callback, data);
+ LA_ITERATE_OVER_SYMBOLS (block, name, domain, callback);
}
/* A helper for find_method. This finds all methods in type T which
static int
decode_line_2_compare_items (const void *ap, const void *bp)
{
- const struct decode_line_2_item *a = ap;
- const struct decode_line_2_item *b = bp;
+ const struct decode_line_2_item *a = (const struct decode_line_2_item *) ap;
+ const struct decode_line_2_item *b = (const struct decode_line_2_item *) bp;
int retval;
retval = strcmp (a->displayform, b->displayform);
struct symtabs_and_lines *result,
const char *select_mode)
{
- char *args, *prompt;
+ char *args;
+ const char *prompt;
int i;
struct cleanup *old_chain;
VEC (const_char_ptr) *filters = NULL;
- struct get_number_or_range_state state;
struct decode_line_2_item *items;
int items_count;
if (args == 0 || *args == 0)
error_no_arg (_("one or more choice numbers"));
- init_number_or_range (&state, args);
- while (!state.finished)
+ number_or_range_parser parser (args);
+ while (!parser.finished ())
{
- int num;
-
- num = get_number_or_range (&state);
+ int num = parser.get_number ();
if (num == 0)
error (_("canceled"));
|| token.type == LSTOKEN_KEYWORD)
{
char *string;
- struct cleanup *cleanup;
string = copy_token_string (token);
- cleanup = make_cleanup (xfree, string);
+ make_cleanup (xfree, string);
throw_error (GENERIC_ERROR,
_("malformed linespec error: unexpected %s, \"%s\""),
token_type_strings[token.type], string);
return;
/* Save everything as an explicit location. */
- canon = state->canonical->location
+ state->canonical->location
= new_explicit_location (&ls->explicit_loc);
+ canon = state->canonical->location.get ();
explicit_loc = get_explicit_location (canon);
if (explicit_loc->label_name != NULL)
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);
+ ls->file_symtabs = collect_symtabs_from_filename (fullname,
+ self->search_pspace);
use_default = 1;
}
TRY
{
result->file_symtabs
- = symtabs_from_filename (explicit_loc->source_filename);
+ = symtabs_from_filename (explicit_loc->source_filename,
+ self->search_pspace);
}
CATCH (except, RETURN_MASK_ERROR)
{
TRY
{
PARSER_RESULT (parser)->file_symtabs
- = symtabs_from_filename (user_filename);
+ = symtabs_from_filename (user_filename,
+ PARSER_STATE (parser)->search_pspace);
}
CATCH (ex, RETURN_MASK_ERROR)
{
static void
linespec_state_constructor (struct linespec_state *self,
int flags, const struct language_defn *language,
+ struct program_space *search_pspace,
struct symtab *default_symtab,
int default_line,
struct linespec_result *canonical)
self->language = language;
self->funfirstline = (flags & DECODE_LINE_FUNFIRSTLINE) ? 1 : 0;
self->list_mode = (flags & DECODE_LINE_LIST_MODE) ? 1 : 0;
+ self->search_pspace = search_pspace;
self->default_symtab = default_symtab;
self->default_line = default_line;
self->canonical = canonical;
static void
linespec_parser_new (linespec_parser *parser,
int flags, const struct language_defn *language,
+ struct program_space *search_pspace,
struct symtab *default_symtab,
int default_line,
struct linespec_result *canonical)
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,
+ search_pspace,
default_symtab, default_line, canonical);
}
if (stringp == NULL || *stringp == NULL)
return;
- linespec_parser_new (&parser, 0, current_language, NULL, 0, NULL);
+ linespec_parser_new (&parser, 0, current_language, NULL, NULL, 0, NULL);
cleanup = make_cleanup (linespec_parser_delete, &parser);
parser.lexer.saved_arg = *stringp;
PARSER_STREAM (&parser) = orig = *stringp;
break;
case ADDRESS_LOCATION:
- result
- = convert_address_location_to_sals (PARSER_STATE (parser),
- get_address_location (location));
+ {
+ const char *addr_string = get_address_string_location (location);
+ CORE_ADDR addr = get_address_location (location);
+
+ if (addr_string != NULL)
+ {
+ char *expr = xstrdup (addr_string);
+ const char *const_expr = expr;
+ struct cleanup *cleanup = make_cleanup (xfree, expr);
+
+ addr = linespec_expression_to_pc (&const_expr);
+ if (PARSER_STATE (parser)->canonical != NULL)
+ PARSER_STATE (parser)->canonical->location
+ = copy_event_location (location);
+
+ do_cleanups (cleanup);
+ }
+
+ result = convert_address_location_to_sals (PARSER_STATE (parser),
+ addr);
+ }
break;
case EXPLICIT_LOCATION:
void
decode_line_full (const struct event_location *location, int flags,
+ struct program_space *search_pspace,
struct symtab *default_symtab,
int default_line, struct linespec_result *canonical,
const char *select_mode,
|| select_mode == multiple_symbols_cancel);
gdb_assert ((flags & DECODE_LINE_LIST_MODE) == 0);
- linespec_parser_new (&parser, flags, current_language, default_symtab,
+ linespec_parser_new (&parser, flags, current_language,
+ search_pspace, default_symtab,
default_line, canonical);
cleanups = make_cleanup (linespec_parser_delete, &parser);
- save_current_program_space ();
+
+ scoped_restore_current_program_space restore_pspace;
result = event_location_to_sals (&parser, location);
state = PARSER_STATE (&parser);
if (select_mode == NULL)
{
- if (ui_out_is_mi_like_p (interp_ui_out (top_level_interpreter ())))
+ if (interp_ui_out (top_level_interpreter ())->is_mi_like_p ())
select_mode = multiple_symbols_all;
else
select_mode = multiple_symbols_select_mode ();
struct symtabs_and_lines
decode_line_1 (const struct event_location *location, int flags,
+ struct program_space *search_pspace,
struct symtab *default_symtab,
int default_line)
{
linespec_parser parser;
struct cleanup *cleanups;
- linespec_parser_new (&parser, flags, current_language, default_symtab,
+ linespec_parser_new (&parser, flags, current_language,
+ search_pspace, default_symtab,
default_line, NULL);
cleanups = make_cleanup (linespec_parser_delete, &parser);
- save_current_program_space ();
+
+ scoped_restore_current_program_space restore_pspace;
result = event_location_to_sals (&parser, location);
{
struct symtabs_and_lines sals;
struct symtab_and_line cursal;
- struct event_location *location;
- struct cleanup *cleanup;
if (string == 0)
error (_("Empty line specification."));
and get a default source symtab+line or it will recursively call us! */
cursal = get_current_source_symtab_and_line ();
- location = string_to_event_location (&string, current_language);
- cleanup = make_cleanup_delete_event_location (location);
- sals = decode_line_1 (location, flags,
+ event_location_up location = string_to_event_location (&string,
+ current_language);
+ sals = decode_line_1 (location.get (), flags, NULL,
cursal.symtab, cursal.line);
if (*string)
error (_("Junk at end of line specification: %s"), string);
- do_cleanups (cleanup);
return sals;
}
decode_line_with_last_displayed (char *string, int flags)
{
struct symtabs_and_lines sals;
- struct event_location *location;
- struct cleanup *cleanup;
if (string == 0)
error (_("Empty line specification."));
- location = string_to_event_location (&string, current_language);
- cleanup = make_cleanup_delete_event_location (location);
+ event_location_up location = string_to_event_location (&string,
+ current_language);
if (last_displayed_sal_is_valid ())
- sals = decode_line_1 (location, flags,
+ sals = decode_line_1 (location.get (), flags, NULL,
get_last_displayed_symtab (),
get_last_displayed_line ());
else
- sals = decode_line_1 (location, flags, (struct symtab *) NULL, 0);
+ sals = decode_line_1 (location.get (), flags, NULL,
+ (struct symtab *) NULL, 0);
if (*string)
error (_("Junk at end of line specification: %s"), string);
- do_cleanups (cleanup);
return sals;
}
{
char *saved_arg;
- saved_arg = alloca (new_argptr - arg + 1);
+ saved_arg = (char *) alloca (new_argptr - arg + 1);
memcpy (saved_arg, arg, new_argptr - arg);
saved_arg[new_argptr - arg] = '\0';
return values;
}
-/* An instance of this type is used when collecting prefix symbols for
- decode_compound. */
+namespace {
-struct decode_compound_collector
+/* A function object that serves as symbol_found_callback_ftype
+ callback for iterate_over_symbols. This is used by
+ lookup_prefix_sym to collect type symbols. */
+class decode_compound_collector
{
- /* The result vector. */
- VEC (symbolp) *symbols;
+public:
+ decode_compound_collector ()
+ : m_symbols (NULL)
+ {
+ m_unique_syms = htab_create_alloc (1, htab_hash_pointer,
+ htab_eq_pointer, NULL,
+ xcalloc, xfree);
+ }
+ ~decode_compound_collector ()
+ {
+ if (m_unique_syms != NULL)
+ htab_delete (m_unique_syms);
+ }
+
+ /* Releases ownership of the collected symbols and returns them. */
+ VEC (symbolp) *release_symbols ()
+ {
+ VEC (symbolp) *res = m_symbols;
+ m_symbols = NULL;
+ return res;
+ }
+
+ /* Callable as a symbol_found_callback_ftype callback. */
+ bool operator () (symbol *sym);
+
+private:
/* A hash table of all symbols we found. We use this to avoid
adding any symbol more than once. */
- htab_t unique_syms;
-};
+ htab_t m_unique_syms;
-/* A callback for iterate_over_symbols that is used by
- lookup_prefix_sym to collect type symbols. */
+ /* The result vector. */
+ VEC (symbolp) *m_symbols;
+};
-static int
-collect_one_symbol (struct symbol *sym, void *d)
+bool
+decode_compound_collector::operator () (symbol *sym)
{
- struct decode_compound_collector *collector = d;
void **slot;
struct type *t;
if (SYMBOL_CLASS (sym) != LOC_TYPEDEF)
- return 1; /* Continue iterating. */
+ return true; /* Continue iterating. */
t = SYMBOL_TYPE (sym);
t = check_typedef (t);
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
&& TYPE_CODE (t) != TYPE_CODE_UNION
&& TYPE_CODE (t) != TYPE_CODE_NAMESPACE)
- return 1; /* Continue iterating. */
+ return true; /* Continue iterating. */
- slot = htab_find_slot (collector->unique_syms, sym, INSERT);
+ slot = htab_find_slot (m_unique_syms, sym, INSERT);
if (!*slot)
{
*slot = sym;
- VEC_safe_push (symbolp, collector->symbols, sym);
+ VEC_safe_push (symbolp, m_symbols, sym);
}
- return 1; /* Continue iterating. */
+ return true; /* Continue iterating. */
}
+} // namespace
+
/* Return any symbols corresponding to CLASS_NAME in FILE_SYMTABS. */
static VEC (symbolp) *
{
int ix;
struct symtab *elt;
- struct decode_compound_collector collector;
- struct cleanup *outer;
- struct cleanup *cleanup;
-
- collector.symbols = NULL;
- outer = make_cleanup (VEC_cleanup (symbolp), &collector.symbols);
-
- collector.unique_syms = htab_create_alloc (1, htab_hash_pointer,
- htab_eq_pointer, NULL,
- xcalloc, xfree);
- cleanup = make_cleanup_htab_delete (collector.unique_syms);
+ decode_compound_collector collector;
for (ix = 0; VEC_iterate (symtab_ptr, file_symtabs, ix, elt); ++ix)
{
if (elt == NULL)
{
iterate_over_all_matching_symtabs (state, class_name, STRUCT_DOMAIN,
- collect_one_symbol, &collector,
- NULL, 0);
+ NULL, false, collector);
iterate_over_all_matching_symtabs (state, class_name, VAR_DOMAIN,
- collect_one_symbol, &collector,
- NULL, 0);
+ NULL, false, collector);
}
else
{
been filtered out earlier. */
gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
set_current_program_space (SYMTAB_PSPACE (elt));
- iterate_over_file_blocks (elt, class_name, STRUCT_DOMAIN,
- collect_one_symbol, &collector);
- iterate_over_file_blocks (elt, class_name, VAR_DOMAIN,
- collect_one_symbol, &collector);
+ iterate_over_file_blocks (elt, class_name, STRUCT_DOMAIN, collector);
+ iterate_over_file_blocks (elt, class_name, VAR_DOMAIN, collector);
}
}
- do_cleanups (cleanup);
- discard_cleanups (outer);
- return collector.symbols;
+ return collector.release_symbols ();
}
/* A qsort comparison function for symbols. The resulting order does
static int
compare_symbols (const void *a, const void *b)
{
- struct symbol * const *sa = a;
- struct symbol * const *sb = b;
+ struct symbol * const *sa = (struct symbol * const*) a;
+ struct symbol * const *sb = (struct symbol * const*) b;
uintptr_t uia, uib;
uia = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (*sa));
static int
compare_msymbols (const void *a, const void *b)
{
- const struct bound_minimal_symbol *sa = a;
- const struct bound_minimal_symbol *sb = b;
+ const struct bound_minimal_symbol *sa
+ = (const struct bound_minimal_symbol *) a;
+ const struct bound_minimal_symbol *sb
+ = (const struct bound_minimal_symbol *) b;
uintptr_t uia, uib;
uia = (uintptr_t) sa->objfile->pspace;
\f
-/* This object is used when collecting all matching symtabs. */
+namespace {
+
+/* This function object is a callback for iterate_over_symtabs, used
+ when collecting all matching symtabs. */
-struct symtab_collector
+class symtab_collector
{
+public:
+ symtab_collector ()
+ {
+ m_symtabs = NULL;
+ m_symtab_table = htab_create (1, htab_hash_pointer, htab_eq_pointer,
+ NULL);
+ }
+
+ ~symtab_collector ()
+ {
+ if (m_symtab_table != NULL)
+ htab_delete (m_symtab_table);
+ }
+
+ /* Callable as a symbol_found_callback_ftype callback. */
+ bool operator () (symtab *sym);
+
+ /* Releases ownership of the collected symtabs and returns them. */
+ VEC (symtab_ptr) *release_symtabs ()
+ {
+ VEC (symtab_ptr) *res = m_symtabs;
+ m_symtabs = NULL;
+ return res;
+ }
+
+private:
/* The result vector of symtabs. */
- VEC (symtab_ptr) *symtabs;
+ VEC (symtab_ptr) *m_symtabs;
/* This is used to ensure the symtabs are unique. */
- htab_t symtab_table;
+ htab_t m_symtab_table;
};
-/* Callback for iterate_over_symtabs. */
-
-static int
-add_symtabs_to_list (struct symtab *symtab, void *d)
+bool
+symtab_collector::operator () (struct symtab *symtab)
{
- struct symtab_collector *data = d;
void **slot;
- slot = htab_find_slot (data->symtab_table, symtab, INSERT);
+ slot = htab_find_slot (m_symtab_table, symtab, INSERT);
if (!*slot)
{
*slot = symtab;
- VEC_safe_push (symtab_ptr, data->symtabs, symtab);
+ VEC_safe_push (symtab_ptr, m_symtabs, symtab);
}
- return 0;
+ return false;
}
-/* Given a file name, return a VEC of all matching symtabs. */
+} // namespace
+
+/* Given a file name, return a VEC of all matching symtabs. If
+ SEARCH_PSPACE is not NULL, the search is restricted to just that
+ program space. */
static VEC (symtab_ptr) *
-collect_symtabs_from_filename (const char *file)
+collect_symtabs_from_filename (const char *file,
+ struct program_space *search_pspace)
{
- struct symtab_collector collector;
- struct cleanup *cleanups;
- struct program_space *pspace;
-
- collector.symtabs = NULL;
- collector.symtab_table = htab_create (1, htab_hash_pointer, htab_eq_pointer,
- NULL);
- cleanups = make_cleanup_htab_delete (collector.symtab_table);
+ symtab_collector collector;
/* Find that file's data. */
- ALL_PSPACES (pspace)
- {
- if (pspace->executing_startup)
- continue;
+ if (search_pspace == NULL)
+ {
+ struct program_space *pspace;
- set_current_program_space (pspace);
- iterate_over_symtabs (file, add_symtabs_to_list, &collector);
- }
+ ALL_PSPACES (pspace)
+ {
+ if (pspace->executing_startup)
+ continue;
- do_cleanups (cleanups);
- return collector.symtabs;
+ set_current_program_space (pspace);
+ iterate_over_symtabs (file, collector);
+ }
+ }
+ else
+ {
+ set_current_program_space (search_pspace);
+ iterate_over_symtabs (file, collector);
+ }
+
+ return collector.release_symtabs ();
}
-/* Return all the symtabs associated to the FILENAME. */
+/* Return all the symtabs associated to the FILENAME. If SEARCH_PSPACE is
+ not NULL, the search is restricted to just that program space. */
static VEC (symtab_ptr) *
-symtabs_from_filename (const char *filename)
+symtabs_from_filename (const char *filename,
+ struct program_space *search_pspace)
{
VEC (symtab_ptr) *result;
- result = collect_symtabs_from_filename (filename);
+ result = collect_symtabs_from_filename (filename, search_pspace);
if (VEC_empty (symtab_ptr, result))
{
/* Try NAME as an Objective-C selector. */
find_imps (name, &symbol_names);
if (!VEC_empty (const_char_ptr, symbol_names))
- add_all_symbol_names_from_pspace (&info, NULL, symbol_names);
+ add_all_symbol_names_from_pspace (&info, state->search_pspace,
+ symbol_names);
else
- add_matching_symbols_to_info (name, &info, NULL);
+ add_matching_symbols_to_info (name, &info, state->search_pspace);
do_cleanups (cleanup);
VEC (symbolp) **symbols,
VEC (bound_minimal_symbol_d) **minsyms)
{
- struct cleanup *cleanup;
- char *canon;
+ demangle_result_storage demangle_storage;
+ std::string ada_lookup_storage;
const char *lookup_name;
- cleanup = demangle_for_lookup (name, state->language->la_language,
- &lookup_name);
if (state->language->la_language == language_ada)
{
/* In Ada, the symbol lookups are performed using the encoded
name rather than the demangled name. */
- lookup_name = ada_name_for_lookup (name);
- make_cleanup (xfree, (void *) lookup_name);
+ ada_lookup_storage = ada_name_for_lookup (name);
+ lookup_name = ada_lookup_storage.c_str ();
}
-
- canon = cp_canonicalize_string_no_typedefs (lookup_name);
- if (canon != NULL)
+ else
{
- lookup_name = canon;
- make_cleanup (xfree, canon);
+ lookup_name = demangle_for_lookup (name,
+ state->language->la_language,
+ demangle_storage);
}
+ std::string canon = cp_canonicalize_string_no_typedefs (lookup_name);
+ if (!canon.empty ())
+ lookup_name = canon.c_str ();
+
/* 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
if (VEC_empty (symbolp, *symbols)
&& VEC_empty (bound_minimal_symbol_d, *minsyms))
{
- char *klass, *method;
+ std::string klass, method;
const char *last, *p, *scope_op;
VEC (symbolp) *classes;
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);
- }
last = NULL;
while (p != NULL)
we already attempted to lookup the entire name as a symbol
and failed. */
if (last == NULL)
- {
- do_cleanups (cleanup);
- return;
- }
+ return;
/* 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';
+ klass = std::string (lookup_name, last - lookup_name);
/* Skip past the scope operator. */
last += strlen (scope_op);
- method = xmalloc ((strlen (last) + 1) * sizeof (char));
- make_cleanup (xfree, method);
- strcpy (method, last);
+ method = last;
/* Find a list of classes named KLASS. */
- classes = lookup_prefix_sym (state, file_symtabs, klass);
- make_cleanup (VEC_cleanup (symbolp), &classes);
+ classes = lookup_prefix_sym (state, file_symtabs, klass.c_str ());
+ struct cleanup *old_chain
+ = make_cleanup (VEC_cleanup (symbolp), &classes);
if (!VEC_empty (symbolp, classes))
{
/* Now locate a list of suitable methods named METHOD. */
TRY
{
- find_method (state, file_symtabs, klass, method, classes,
- symbols, minsyms);
+ find_method (state, file_symtabs,
+ klass.c_str (), method.c_str (),
+ classes, symbols, minsyms);
}
/* If successful, we're done. If NOT_FOUND_ERROR
}
END_CATCH
}
- }
- do_cleanups (cleanup);
+ do_cleanups (old_chain);
+ }
}
/* Return all labels named NAME in FUNCTION_SYMBOLS. Return the
for (ix = 0; VEC_iterate (symtab_ptr, ls->file_symtabs, ix, elt); ++ix)
{
- int i;
- VEC (CORE_ADDR) *pcs;
- CORE_ADDR pc;
+ std::vector<CORE_ADDR> pcs;
/* The logic above should ensure this. */
gdb_assert (elt != NULL);
set_current_program_space (SYMTAB_PSPACE (elt));
pcs = find_pcs_for_symtab_line (elt, line, best_entry);
- for (i = 0; VEC_iterate (CORE_ADDR, pcs, i, pc); ++i)
+ for (CORE_ADDR pc : pcs)
{
struct symtab_and_line sal;
sal.pc = pc;
add_sal_to_sals_basic (sals, &sal);
}
-
- VEC_free (CORE_ADDR, pcs);
}
}
}
\f
-/* A callback used to possibly add a symbol to the results. */
-
-static int
-collect_symbols (struct symbol *sym, void *data)
-{
- struct collect_info *info = 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);
- return 1; /* Continue iterating. */
-}
-
/* We've found a minimal symbol MSYMBOL in OBJFILE to associate with our
linespec; return the SAL in RESULT. This function should return SALs
matching those from find_function_start_sal, otherwise false
static int
compare_msyms (const void *a, const void *b)
{
- const bound_minimal_symbol_d *moa = a;
- const bound_minimal_symbol_d *mob = b;
+ const bound_minimal_symbol_d *moa = (const bound_minimal_symbol_d *) a;
+ const bound_minimal_symbol_d *mob = (const bound_minimal_symbol_d *) b;
enum minimal_symbol_type ta = MSYMBOL_TYPE (moa->minsym);
enum minimal_symbol_type tb = MSYMBOL_TYPE (mob->minsym);
static void
add_minsym (struct minimal_symbol *minsym, void *d)
{
- struct collect_minsyms *info = d;
+ struct collect_minsyms *info = (struct collect_minsyms *) d;
bound_minimal_symbol_d mo;
mo.minsym = minsym;
if (elt == NULL)
{
iterate_over_all_matching_symtabs (info->state, name, VAR_DOMAIN,
- collect_symbols, info,
- pspace, 1);
+ pspace, true, [&] (symbol *sym)
+ { return info->add_symbol (sym); });
search_minsyms_for_name (info, name, pspace, NULL);
}
else if (pspace == NULL || pspace == SYMTAB_PSPACE (elt))
been filtered out earlier. */
gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
set_current_program_space (SYMTAB_PSPACE (elt));
- iterate_over_file_blocks (elt, name, VAR_DOMAIN,
- collect_symbols, info);
+ iterate_over_file_blocks (elt, name, VAR_DOMAIN, [&] (symbol *sym)
+ { return info->add_symbol (sym); });
/* If no new symbols were found in this iteration and this symtab
is in assembler, we might actually be looking for a label for
return 0;
}
-/* See the comment in linespec.h. */
-
-void
-init_linespec_result (struct linespec_result *lr)
-{
- memset (lr, 0, sizeof (*lr));
-}
-
-/* See the comment in linespec.h. */
-
-void
-destroy_linespec_result (struct linespec_result *ls)
+linespec_result::~linespec_result ()
{
int i;
struct linespec_sals *lsal;
- delete_event_location (ls->location);
- for (i = 0; VEC_iterate (linespec_sals, ls->sals, i, lsal); ++i)
+ for (i = 0; VEC_iterate (linespec_sals, sals, i, lsal); ++i)
{
xfree (lsal->canonical);
xfree (lsal->sals.sals);
}
- VEC_free (linespec_sals, ls->sals);
-}
-
-/* Cleanup function for a linespec_result. */
-
-static void
-cleanup_linespec_result (void *a)
-{
- destroy_linespec_result (a);
-}
-
-/* See the comment in linespec.h. */
-
-struct cleanup *
-make_cleanup_destroy_linespec_result (struct linespec_result *ls)
-{
- return make_cleanup (cleanup_linespec_result, ls);
+ VEC_free (linespec_sals, sals);
}
/* Return the quote characters permitted by the linespec parser. */