X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Flinespec.c;h=acf4900d456439077ce6cf17d5d4d7d7fcc00e92;hb=c94fee56f5f8e5e26a115a1ca155ddada9d43b31;hp=50951bdd80c9839a1976381737e9231c1c14b58c;hpb=618f726fcb851883a0094aa7fa17003889b7189f;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/linespec.c b/gdb/linespec.c index 50951bdd80..acf4900d45 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -1,6 +1,6 @@ /* Parser for linespec for the GNU debugger, GDB. - Copyright (C) 1986-2016 Free Software Foundation, Inc. + Copyright (C) 1986-2017 Free Software Foundation, Inc. This file is part of GDB. @@ -44,6 +44,7 @@ #include "ada-lang.h" #include "stack.h" #include "location.h" +#include "common/function-view.h" typedef struct symbol *symbolp; DEF_VEC_P (symbolp); @@ -123,6 +124,10 @@ struct linespec_state /* 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; @@ -167,8 +172,23 @@ struct collect_info 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 @@ -260,10 +280,9 @@ typedef struct ls_parser linespec_parser; /* 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 callback); static void initialize_defaults (struct symtab **default_symtab, int *default_line); @@ -274,7 +293,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 *, + struct program_space *pspace); static VEC (symbolp) *find_label_symbols (struct linespec_state *self, VEC (symbolp) *function_symbols, @@ -302,7 +322,9 @@ 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, + struct program_space *pspace); static void decode_digits_ordinary (struct linespec_state *self, linespec_p ls, @@ -838,7 +860,7 @@ add_sal_to_sals (struct linespec_state *self, 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 @@ -909,83 +931,26 @@ maybe_add_address (htab_t set, struct program_space *pspace, CORE_ADDR 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 - = (struct symbol_and_data_callback *) 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 - = (const struct symbol_matcher_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 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) { @@ -1001,20 +966,24 @@ iterate_over_all_matching_symtabs (struct linespec_state *state, 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; @@ -1024,7 +993,14 @@ iterate_over_all_matching_symtabs (struct linespec_state *state, { 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; + }); } } } @@ -1053,16 +1029,16 @@ get_current_search_block (void) /* 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 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 @@ -1317,11 +1293,11 @@ decode_line_2 (struct linespec_state *self, 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; @@ -1402,12 +1378,10 @@ decode_line_2 (struct linespec_state *self, 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")); @@ -1512,10 +1486,9 @@ unexpected_linespec_error (linespec_parser *parser) || 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); @@ -1777,8 +1750,9 @@ canonicalize_linespec (struct linespec_state *state, const linespec_p ls) 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) @@ -1842,7 +1816,8 @@ 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); + ls->file_symtabs = collect_symtabs_from_filename (fullname, + self->search_pspace); use_default = 1; } @@ -2094,7 +2069,8 @@ convert_explicit_location_to_sals (struct linespec_state *self, 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) { @@ -2285,7 +2261,8 @@ parse_linespec (linespec_parser *parser, const char *arg) 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) { @@ -2367,6 +2344,7 @@ 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 program_space *search_pspace, struct symtab *default_symtab, int default_line, struct linespec_result *canonical) @@ -2375,6 +2353,7 @@ linespec_state_constructor (struct linespec_state *self, 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; @@ -2389,6 +2368,7 @@ linespec_state_constructor (struct linespec_state *self, 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) @@ -2398,6 +2378,7 @@ linespec_parser_new (linespec_parser *parser, 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); } @@ -2451,7 +2432,7 @@ linespec_lex_to_end (char **stringp) 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; @@ -2498,9 +2479,27 @@ event_location_to_sals (linespec_parser *parser, 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: @@ -2530,6 +2529,7 @@ event_location_to_sals (linespec_parser *parser, 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, @@ -2550,7 +2550,8 @@ decode_line_full (const struct event_location *location, int flags, || 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 (); @@ -2576,7 +2577,7 @@ decode_line_full (const struct event_location *location, int flags, 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 (); @@ -2603,6 +2604,7 @@ decode_line_full (const struct event_location *location, int flags, 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) { @@ -2610,7 +2612,8 @@ decode_line_1 (const struct event_location *location, int flags, 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 (); @@ -2628,8 +2631,6 @@ decode_line_with_current_source (char *string, int flags) { struct symtabs_and_lines sals; struct symtab_and_line cursal; - struct event_location *location; - struct cleanup *cleanup; if (string == 0) error (_("Empty line specification.")); @@ -2638,15 +2639,14 @@ decode_line_with_current_source (char *string, int flags) 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; } @@ -2656,25 +2656,23 @@ struct symtabs_and_lines 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; } @@ -2792,50 +2790,76 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char *arg) 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 - = (struct decode_compound_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) * @@ -2844,28 +2868,16 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs, { 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 { @@ -2873,16 +2885,12 @@ lookup_prefix_sym (struct linespec_state *state, VEC (symtab_ptr) *file_symtabs, 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 @@ -3088,71 +3096,106 @@ find_method (struct linespec_state *self, VEC (symtab_ptr) *file_symtabs, -/* This object is used when collecting all matching symtabs. */ +namespace { -struct symtab_collector +/* This function object is a callback for iterate_over_symtabs, used + when collecting all matching symtabs. */ + +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 = (struct symtab_collector *) 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)) { @@ -3189,9 +3232,10 @@ find_function_symbols (struct linespec_state *state, /* 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); @@ -3222,27 +3266,28 @@ find_linespec_symbols (struct linespec_state *state, 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 @@ -3261,7 +3306,7 @@ find_linespec_symbols (struct linespec_state *state, 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; @@ -3269,12 +3314,6 @@ find_linespec_symbols (struct linespec_state *state, 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) @@ -3287,35 +3326,29 @@ find_linespec_symbols (struct linespec_state *state, 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 = XNEWVEC (char, last - lookup_name + 1); - 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 = XNEWVEC (char, strlen (last) + 1); - 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 @@ -3327,9 +3360,9 @@ find_linespec_symbols (struct linespec_state *state, } END_CATCH } - } - do_cleanups (cleanup); + do_cleanups (old_chain); + } } /* Return all labels named NAME in FUNCTION_SYMBOLS. Return the @@ -3437,9 +3470,7 @@ decode_digits_ordinary (struct linespec_state *self, for (ix = 0; VEC_iterate (symtab_ptr, ls->file_symtabs, ix, elt); ++ix) { - int i; - VEC (CORE_ADDR) *pcs; - CORE_ADDR pc; + std::vector pcs; /* The logic above should ensure this. */ gdb_assert (elt != NULL); @@ -3447,7 +3478,7 @@ decode_digits_ordinary (struct linespec_state *self, 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; @@ -3458,8 +3489,6 @@ decode_digits_ordinary (struct linespec_state *self, sal.pc = pc; add_sal_to_sals_basic (sals, &sal); } - - VEC_free (CORE_ADDR, pcs); } } @@ -3522,20 +3551,6 @@ linespec_parse_variable (struct linespec_state *self, const char *variable) } -/* A callback used to possibly add a symbol to the results. */ - -static int -collect_symbols (struct symbol *sym, void *data) -{ - struct collect_info *info = (struct collect_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 @@ -3803,8 +3818,8 @@ add_matching_symbols_to_info (const char *name, 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)) @@ -3815,8 +3830,8 @@ add_matching_symbols_to_info (const char *name, 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 @@ -3873,45 +3888,17 @@ symbol_to_sal (struct symtab_and_line *result, 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 ((struct 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. */