/* Parser for linespec for the GNU debugger, GDB.
- Copyright (C) 1986-2019 Free Software Foundation, Inc.
+ Copyright (C) 1986-2022 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"
-#include "common/def-vector.h"
+#include "gdbsupport/function-view.h"
+#include "gdbsupport/def-vector.h"
#include <algorithm>
+#include "inferior.h"
/* An enumeration of the various things a user might attempt to
complete for a linespec location. */
/* An expression. E.g., "break foo if EXPR", or "break *EXPR". */
EXPRESSION,
- /* A linespec keyword ("if"/"thread"/"task").
+ /* A linespec keyword ("if"/"thread"/"task"/"-force-condition").
E.g., "break func threa<tab>". */
KEYWORD,
};
struct linespec
{
/* An explicit location describing the SaLs. */
- struct explicit_location explicit_loc;
+ struct explicit_location explicit_loc {};
- /* The list of symtabs to search to which to limit the search. May not
- be NULL. If explicit.SOURCE_FILENAME is NULL (no user-specified
- filename), FILE_SYMTABS should contain one single NULL member. This
- will cause the code to use the default symtab. */
- std::vector<symtab *> *file_symtabs;
+ /* The list of symtabs to search to which to limit the search.
+
+ If explicit.SOURCE_FILENAME is NULL (no user-specified filename),
+ FILE_SYMTABS should contain one single NULL member. This will cause the
+ code to use the default symtab. */
+ std::vector<symtab *> file_symtabs;
/* A list of matching function symbols and minimal symbols. Both lists
- may be NULL (or empty) if no matching symbols were found. */
- std::vector<block_symbol> *function_symbols;
- std::vector<bound_minimal_symbol> *minimal_symbols;
+ may be empty if no matching symbols were found. */
+ std::vector<block_symbol> function_symbols;
+ std::vector<bound_minimal_symbol> minimal_symbols;
/* A structure of matching label symbols and the corresponding
- function symbol in which the label was found. Both may be NULL
- or both must be non-NULL. */
+ function symbol in which the label was found. Both may be empty
+ or both must be non-empty. */
struct
{
- std::vector<block_symbol> *label_symbols;
- std::vector<block_symbol> *function_symbols;
+ std::vector<block_symbol> label_symbols;
+ std::vector<block_symbol> function_symbols;
} labels;
};
-typedef struct linespec *linespec_p;
/* A canonical linespec represented as a symtab-related string.
struct linespec_state *state;
/* A list of symtabs to which to restrict matches. */
- std::vector<symtab *> *file_symtabs;
+ const std::vector<symtab *> *file_symtabs;
/* The result being accumulated. */
struct
{
/* In list mode, add all matching symbols, regardless of class.
This allows the user to type "list a_global_variable". */
- if (SYMBOL_CLASS (bsym->symbol) == LOC_BLOCK || this->state->list_mode)
+ if (bsym->symbol->aclass () == LOC_BLOCK || this->state->list_mode)
this->result.symbols->push_back (*bsym);
/* Continue iterating. */
/* List of keywords. This is NULL-terminated so that it can be used
as enum completer. */
-const char * const linespec_keywords[] = { "if", "thread", "task", NULL };
+const char * const linespec_keywords[] = { "if", "thread", "task", "-force-condition", NULL };
#define IF_KEYWORD_INDEX 0
+#define FORCE_KEYWORD_INDEX 3
/* A token of the linespec lexer */
-struct ls_token
+struct linespec_token
{
/* The type of the token */
linespec_token_type type;
const char *keyword;
} data;
};
-typedef struct ls_token linespec_token;
#define LS_TOKEN_STOKEN(TOK) (TOK).data.string
#define LS_TOKEN_KEYWORD(TOK) (TOK).data.keyword
#define PARSER_STATE(PPTR) (&(PPTR)->state)
/* The result of the parse. */
- struct linespec result {};
+ linespec result;
#define PARSER_RESULT(PPTR) (&(PPTR)->result)
/* What the parser believes the current word point should complete
CORE_ADDR linespec_expression_to_pc (const char **exp_ptr);
static std::vector<symtab_and_line> decode_objc (struct linespec_state *self,
- linespec_p ls,
+ linespec *ls,
const char *arg);
static std::vector<symtab *> symtabs_from_filename
(const char *, struct program_space *pspace);
-static std::vector<block_symbol> *find_label_symbols
- (struct linespec_state *self, std::vector<block_symbol> *function_symbols,
- std::vector<block_symbol> *label_funcs_ret, const char *name,
- bool completion_mode = false);
+static std::vector<block_symbol> find_label_symbols
+ (struct linespec_state *self,
+ const std::vector<block_symbol> &function_symbols,
+ std::vector<block_symbol> *label_funcs_ret,
+ const char *name, bool completion_mode = false);
static void find_linespec_symbols (struct linespec_state *self,
- std::vector<symtab *> *file_symtabs,
+ const std::vector<symtab *> &file_symtabs,
const char *name,
symbol_name_match_type name_match_type,
std::vector<block_symbol> *symbols,
static std::vector<symtab_and_line> decode_digits_ordinary
(struct linespec_state *self,
- linespec_p ls,
+ linespec *ls,
int line,
linetable_entry **best_entry);
static std::vector<symtab_and_line> decode_digits_list_mode
(struct linespec_state *self,
- linespec_p ls,
+ linespec *ls,
struct symtab_and_line val);
static void minsym_found (struct linespec_state *self, struct objfile *objfile,
/* Permitted quote characters for the parser. This is different from the
completer's quote characters to allow backward compatibility with the
previous parser. */
-static const char *const linespec_quote_characters = "\"\'";
+static const char linespec_quote_characters[] = "\"\'";
/* Lexer functions. */
{
int len = strlen (linespec_keywords[i]);
- /* If P begins with one of the keywords and the next
- character is whitespace, we may have found a keyword.
- It is only a keyword if it is not followed by another
- keyword. */
- if (strncmp (p, linespec_keywords[i], len) == 0
- && isspace (p[len]))
+ /* If P begins with
+
+ - "thread" or "task" and the next character is
+ whitespace, we may have found a keyword. It is only a
+ keyword if it is not followed by another keyword.
+
+ - "-force-condition", the next character may be EOF
+ since this keyword does not take any arguments. Otherwise,
+ it should be followed by a keyword.
+
+ - "if", ALWAYS stop the lexer, since it is not possible to
+ predict what is going to appear in the condition, which can
+ only be parsed after SaLs have been found. */
+ if (strncmp (p, linespec_keywords[i], len) == 0)
{
int j;
- /* Special case: "if" ALWAYS stops the lexer, since it
- is not possible to predict what is going to appear in
- the condition, which can only be parsed after SaLs have
- been found. */
- if (i != IF_KEYWORD_INDEX)
+ if (i == FORCE_KEYWORD_INDEX && p[len] == '\0')
+ return linespec_keywords[i];
+
+ if (!isspace (p[len]))
+ continue;
+
+ if (i == FORCE_KEYWORD_INDEX)
{
+ p += len;
+ p = skip_spaces (p);
+ for (j = 0; linespec_keywords[j] != NULL; ++j)
+ {
+ int nextlen = strlen (linespec_keywords[j]);
+
+ if (strncmp (p, linespec_keywords[j], nextlen) == 0
+ && isspace (p[nextlen]))
+ return linespec_keywords[i];
+ }
+ }
+ else if (i != IF_KEYWORD_INDEX)
+ {
+ /* We matched a "thread" or "task". */
p += len;
p = skip_spaces (p);
for (j = 0; linespec_keywords[j] != NULL; ++j)
const char *str, *s;
if (token.type == LSTOKEN_KEYWORD)
- return gdb::unique_xmalloc_ptr<char> (xstrdup (LS_TOKEN_KEYWORD (token)));
+ return make_unique_xstrdup (LS_TOKEN_KEYWORD (token));
str = LS_TOKEN_STOKEN (token).ptr;
s = remove_trailing_whitespace (str, str + LS_TOKEN_STOKEN (token).length);
/* Do not tokenize ABI tags such as "[abi:cxx11]". */
else if (PARSER_STREAM (parser) - start > 4
&& startswith (PARSER_STREAM (parser) - 4, "[abi"))
- ++(PARSER_STREAM (parser));
+ {
+ /* Nothing. */
+ }
/* Do not tokenify if the input length so far is one
(i.e, a single-letter drive name) and the next character
}
/* Advance the stream. */
+ gdb_assert (*(PARSER_STREAM (parser)) != '\0');
++(PARSER_STREAM (parser));
}
}
case '+': case '-':
case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- if (!linespec_lexer_lex_number (parser, &(parser->lexer.current)))
+ case '5': case '6': case '7': case '8': case '9':
+ if (!linespec_lexer_lex_number (parser, &(parser->lexer.current)))
parser->lexer.current = linespec_lexer_lex_string (parser);
- break;
+ break;
case ':':
/* If we have a scope operator, lex the input as a string.
the time being. */
if (symname != NULL && sal->line != 0
&& self->language->la_language == language_ada)
- canonical->suffix = xstrprintf ("%s:%d", symname, sal->line);
+ canonical->suffix = xstrprintf ("%s:%d", symname,
+ sal->line).release ();
else if (symname != NULL)
canonical->suffix = xstrdup (symname);
else
- canonical->suffix = xstrprintf ("%d", sal->line);
+ canonical->suffix = xstrprintf ("%d", sal->line).release ();
canonical->symtab = sal->symtab;
}
else
struct program_space *search_pspace, bool include_inline,
gdb::function_view<symbol_found_callback_ftype> callback)
{
- struct objfile *objfile;
- struct program_space *pspace;
-
- ALL_PSPACES (pspace)
- {
- if (search_pspace != NULL && search_pspace != pspace)
- continue;
- if (pspace->executing_startup)
- continue;
-
- set_current_program_space (pspace);
-
- ALL_OBJFILES (objfile)
+ for (struct program_space *pspace : program_spaces)
{
- struct compunit_symtab *cu;
+ if (search_pspace != NULL && search_pspace != pspace)
+ continue;
+ if (pspace->executing_startup)
+ continue;
- if (objfile->sf)
- objfile->sf->qf->expand_symtabs_matching (objfile,
- NULL,
- lookup_name,
- NULL, NULL,
- search_domain);
+ set_current_program_space (pspace);
- ALL_OBJFILE_COMPUNITS (objfile, cu)
+ for (objfile *objfile : current_program_space->objfiles ())
{
- struct symtab *symtab = COMPUNIT_FILETABS (cu);
-
- iterate_over_file_blocks (symtab, lookup_name, name_domain, callback);
+ objfile->expand_symtabs_matching (NULL, &lookup_name, NULL, NULL,
+ (SEARCH_GLOBAL_BLOCK
+ | SEARCH_STATIC_BLOCK),
+ UNDEF_DOMAIN,
+ search_domain);
- if (include_inline)
+ for (compunit_symtab *cu : objfile->compunits ())
{
- struct block *block;
- int i;
+ struct symtab *symtab = cu->primary_filetab ();
- for (i = FIRST_LOCAL_BLOCK;
- i < BLOCKVECTOR_NBLOCKS (SYMTAB_BLOCKVECTOR (symtab));
- i++)
+ iterate_over_file_blocks (symtab, lookup_name, name_domain,
+ callback);
+
+ if (include_inline)
{
- block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i);
- state->language->la_iterate_over_symbols
- (block, lookup_name, name_domain, [&] (block_symbol *bsym)
- {
- /* Restrict calls to CALLBACK to symbols
- representing inline symbols only. */
- if (SYMBOL_INLINED (bsym->symbol))
- return callback (bsym);
- return true;
- });
+ const struct block *block;
+ int i;
+
+ for (i = FIRST_LOCAL_BLOCK;
+ i < BLOCKVECTOR_NBLOCKS (symtab->blockvector ());
+ i++)
+ {
+ block = BLOCKVECTOR_BLOCK (symtab->blockvector (), i);
+ state->language->iterate_over_symbols
+ (block, lookup_name, name_domain,
+ [&] (block_symbol *bsym)
+ {
+ /* Restrict calls to CALLBACK to symbols
+ representing inline symbols only. */
+ if (bsym->symbol->is_inlined ())
+ return callback (bsym);
+ return true;
+ });
+ }
}
}
}
}
- }
}
/* Returns the block to be used for symbol searches from
static const struct block *
get_current_search_block (void)
{
- const struct block *block;
- enum language save_language;
-
/* get_selected_block can change the current language when there is
no selected frame yet. */
- save_language = current_language->la_language;
- block = get_selected_block (0);
- set_language (save_language);
-
- return block;
+ scoped_restore_current_language save_language;
+ return get_selected_block (0);
}
/* Iterate over static and global blocks. */
(struct symtab *symtab, const lookup_name_info &name,
domain_enum domain, gdb::function_view<symbol_found_callback_ftype> callback)
{
- struct block *block;
+ const struct block *block;
- for (block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), STATIC_BLOCK);
+ for (block = BLOCKVECTOR_BLOCK (symtab->blockvector (), STATIC_BLOCK);
block != NULL;
block = BLOCK_SUPERBLOCK (block))
- LA_ITERATE_OVER_SYMBOLS (block, name, domain, callback);
+ current_language->iterate_over_symbols (block, name, domain, callback);
}
/* A helper for find_method. This finds all methods in type T of
std::vector<struct type *> *superclasses)
{
int ibase;
- const char *class_name = TYPE_NAME (t);
+ const char *class_name = t->name ();
/* Ignore this class if it doesn't have a name. This is ugly, but
unless we figure out how to get the physname without the name of
int method_counter;
lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
symbol_name_matcher_ftype *symbol_name_compare
- = get_symbol_name_matcher (language_def (t_lang), lookup_name);
+ = language_def (t_lang)->get_symbol_name_matcher (lookup_name);
t = check_typedef (t);
/* Loop over each method name. At this level, all overloads of a name
- are counted as a single name. There is an inner loop which loops over
- each overload. */
+ are counted as a single name. There is an inner loop which loops over
+ each overload. */
for (method_counter = TYPE_NFN_FIELDS (t) - 1;
method_counter >= 0;
--method_counter)
{
const char *method_name = TYPE_FN_FIELDLIST_NAME (t, method_counter);
- char dem_opname[64];
-
- if (startswith (method_name, "__") ||
- startswith (method_name, "op") ||
- startswith (method_name, "type"))
- {
- if (cplus_demangle_opname (method_name, dem_opname, DMGL_ANSI))
- method_name = dem_opname;
- else if (cplus_demangle_opname (method_name, dem_opname, 0))
- method_name = dem_opname;
- }
if (symbol_name_compare (method_name, lookup_name, NULL))
{
/* A structure that contains two string representations of a struct
linespec_canonical_name:
- - one where the the symtab's fullname is used;
+ - one where the symtab's fullname is used;
- one where the filename followed the "set filename-display"
setting. */
std::vector<symtab_and_line> *result,
const char *select_mode)
{
- char *args;
+ const char *args;
const char *prompt;
int i;
std::vector<const char *> filters;
{
if (function != NULL)
throw_error (NOT_FOUND_ERROR,
- _("No label \"%s\" defined in function \"%s\"."),
- label, function);
+ _("No label \"%s\" defined in function \"%s\"."),
+ label, function);
else
throw_error (NOT_FOUND_ERROR,
- _("No label \"%s\" defined in current function."),
- label);
+ _("No label \"%s\" defined in current function."),
+ label);
}
/* Throw a source file not found error. */
{
gdb::unique_xmalloc_ptr<char> name;
linespec_token token;
- std::vector<block_symbol> symbols;
- std::vector<block_symbol> *labels;
- std::vector<bound_minimal_symbol> minimal_symbols;
/* Get the next token. */
token = linespec_lexer_lex_one (parser);
}
else
{
+ std::vector<block_symbol> symbols;
+ std::vector<bound_minimal_symbol> minimal_symbols;
+
/* Try looking it up as a function/method. */
find_linespec_symbols (PARSER_STATE (parser),
PARSER_RESULT (parser)->file_symtabs, name.get (),
if (!symbols.empty () || !minimal_symbols.empty ())
{
- PARSER_RESULT (parser)->function_symbols
- = new std::vector<block_symbol> (std::move (symbols));
- PARSER_RESULT (parser)->minimal_symbols
- = new std::vector<bound_minimal_symbol>
- (std::move (minimal_symbols));
+ PARSER_RESULT (parser)->function_symbols = std::move (symbols);
+ PARSER_RESULT (parser)->minimal_symbols = std::move (minimal_symbols);
PARSER_EXPLICIT (parser)->function_name = name.release ();
}
else
{
/* NAME was not a function or a method. So it must be a label
name or user specified variable like "break foo.c:$zippo". */
- labels = find_label_symbols (PARSER_STATE (parser), NULL,
- &symbols, name.get ());
- if (labels != NULL)
+ std::vector<block_symbol> labels
+ = find_label_symbols (PARSER_STATE (parser), {}, &symbols,
+ name.get ());
+
+ if (!labels.empty ())
{
- PARSER_RESULT (parser)->labels.label_symbols = labels;
+ PARSER_RESULT (parser)->labels.label_symbols = std::move (labels);
PARSER_RESULT (parser)->labels.function_symbols
- = new std::vector<block_symbol> (std::move (symbols));
+ = std::move (symbols);
PARSER_EXPLICIT (parser)->label_name = name.release ();
}
else if (token.type == LSTOKEN_STRING
}
else
{
+ std::vector<block_symbol> symbols;
+
/* Grab a copy of the label's name and look it up. */
name = copy_token_string (token);
- labels
+ std::vector<block_symbol> labels
= find_label_symbols (PARSER_STATE (parser),
PARSER_RESULT (parser)->function_symbols,
&symbols, name.get ());
- if (labels != NULL)
+ if (!labels.empty ())
{
- PARSER_RESULT (parser)->labels.label_symbols = labels;
+ PARSER_RESULT (parser)->labels.label_symbols
+ = std::move (labels);
PARSER_RESULT (parser)->labels.function_symbols
- = new std::vector<block_symbol> (std::move (symbols));
+ = std::move (symbols);
PARSER_EXPLICIT (parser)->label_name = name.release ();
}
else
locations. */
static void
-canonicalize_linespec (struct linespec_state *state, const linespec_p ls)
+canonicalize_linespec (struct linespec_state *state, const linespec *ls)
{
struct event_location *canon;
struct explicit_location *explicit_loc;
if (explicit_loc->function_name == NULL)
{
/* No function was specified, so add the symbol name. */
- gdb_assert (!ls->labels.function_symbols->empty ()
- && (ls->labels.function_symbols->size () == 1));
- block_symbol s = ls->labels.function_symbols->front ();
- explicit_loc->function_name
- = xstrdup (SYMBOL_NATURAL_NAME (s.symbol));
+ gdb_assert (ls->labels.function_symbols.size () == 1);
+ block_symbol s = ls->labels.function_symbols.front ();
+ explicit_loc->function_name = xstrdup (s.symbol->natural_name ());
}
}
/* If this location originally came from a linespec, save a string
representation of it for display and saving to file. */
if (state->is_linespec)
- {
- char *linespec = explicit_location_to_linespec (explicit_loc);
-
- set_event_location_string (canon, linespec);
- xfree (linespec);
- }
+ set_event_location_string (canon,
+ explicit_location_to_linespec (explicit_loc));
}
/* Given a line offset in LS, construct the relevant SALs. */
static std::vector<symtab_and_line>
create_sals_line_offset (struct linespec_state *self,
- linespec_p ls)
+ linespec *ls)
{
int use_default = 0;
set_default_source_symtab_and_line uses
select_source_symtab that calls us with such an argument. */
- if (ls->file_symtabs->size () == 1
- && ls->file_symtabs->front () == nullptr)
+ if (ls->file_symtabs.size () == 1
+ && ls->file_symtabs.front () == nullptr)
{
- const char *fullname;
-
set_current_program_space (self->program_space);
/* Make sure we have at least a default source line. */
set_default_source_symtab_and_line ();
initialize_defaults (&self->default_symtab, &self->default_line);
- fullname = symtab_to_fullname (self->default_symtab);
- *ls->file_symtabs
- = collect_symtabs_from_filename (fullname, self->search_pspace);
+ ls->file_symtabs
+ = collect_symtabs_from_filename (self->default_symtab->filename,
+ self->search_pspace);
use_default = 1;
}
skip_prologue_sal (&intermediate_results[i]);
intermediate_results[i].symbol = sym;
add_sal_to_sals (self, &values, &intermediate_results[i],
- sym ? SYMBOL_NATURAL_NAME (sym) : NULL, 0);
+ sym ? sym->natural_name () : NULL, 0);
}
}
/* Create and return SALs from the linespec LS. */
static std::vector<symtab_and_line>
-convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
+convert_linespec_to_sals (struct linespec_state *state, linespec *ls)
{
std::vector<symtab_and_line> sals;
- if (ls->labels.label_symbols != NULL)
+ if (!ls->labels.label_symbols.empty ())
{
/* We have just a bunch of functions/methods or labels. */
struct symtab_and_line sal;
- for (const auto &sym : *ls->labels.label_symbols)
+ for (const auto &sym : ls->labels.label_symbols)
{
struct program_space *pspace
- = SYMTAB_PSPACE (symbol_symtab (sym.symbol));
+ = symbol_symtab (sym.symbol)->pspace ();
if (symbol_to_sal (&sal, state->funfirstline, sym.symbol)
&& maybe_add_address (state->addr_set, pspace, sal.pc))
add_sal_to_sals (state, &sals, &sal,
- SYMBOL_NATURAL_NAME (sym.symbol), 0);
+ sym.symbol->natural_name (), 0);
}
}
- else if (ls->function_symbols != NULL || ls->minimal_symbols != NULL)
+ else if (!ls->function_symbols.empty () || !ls->minimal_symbols.empty ())
{
/* We have just a bunch of functions and/or methods. */
- if (ls->function_symbols != NULL)
+ if (!ls->function_symbols.empty ())
{
/* Sort symbols so that symbols with the same program space are next
to each other. */
- std::sort (ls->function_symbols->begin (),
- ls->function_symbols->end (),
+ std::sort (ls->function_symbols.begin (),
+ ls->function_symbols.end (),
compare_symbols);
- for (const auto &sym : *ls->function_symbols)
+ for (const auto &sym : ls->function_symbols)
{
program_space *pspace
- = SYMTAB_PSPACE (symbol_symtab (sym.symbol));
+ = symbol_symtab (sym.symbol)->pspace ();
set_current_program_space (pspace);
/* Don't skip to the first line of the function if we
bool found_ifunc = false;
if (state->funfirstline
- && ls->minimal_symbols != NULL
- && SYMBOL_CLASS (sym.symbol) == LOC_BLOCK)
+ && !ls->minimal_symbols.empty ()
+ && sym.symbol->aclass () == LOC_BLOCK)
{
const CORE_ADDR addr
= BLOCK_ENTRY_PC (SYMBOL_BLOCK_VALUE (sym.symbol));
- for (const auto &elem : *ls->minimal_symbols)
+ for (const auto &elem : ls->minimal_symbols)
{
if (MSYMBOL_TYPE (elem.minsym) == mst_text_gnu_ifunc
|| MSYMBOL_TYPE (elem.minsym) == mst_data_gnu_ifunc)
if (MSYMBOL_TYPE (elem.minsym) == mst_data_gnu_ifunc)
{
struct gdbarch *gdbarch
- = get_objfile_arch (elem.objfile);
+ = elem.objfile->arch ();
msym_addr
= (gdbarch_convert_from_func_ptr_addr
(gdbarch,
msym_addr,
- current_top_target ()));
+ current_inferior ()->top_target ()));
}
if (msym_addr == addr)
if (symbol_to_sal (&sal, state->funfirstline, sym.symbol)
&& maybe_add_address (state->addr_set, pspace, sal.pc))
add_sal_to_sals (state, &sals, &sal,
- SYMBOL_NATURAL_NAME (sym.symbol), 0);
+ sym.symbol->natural_name (), 0);
}
}
}
- if (ls->minimal_symbols != NULL)
+ if (!ls->minimal_symbols.empty ())
{
/* Sort minimal symbols by program space, too */
- std::sort (ls->minimal_symbols->begin (),
- ls->minimal_symbols->end (),
+ std::sort (ls->minimal_symbols.begin (),
+ ls->minimal_symbols.end (),
compare_msymbols);
- for (const auto &elem : *ls->minimal_symbols)
+ for (const auto &elem : ls->minimal_symbols)
{
program_space *pspace = elem.objfile->pspace;
set_current_program_space (pspace);
static void
convert_explicit_location_to_linespec (struct linespec_state *self,
- linespec_p result,
+ linespec *result,
const char *source_filename,
const char *function_name,
symbol_name_match_type fname_match_type,
const char *label_name,
struct line_offset line_offset)
{
- std::vector<block_symbol> symbols;
- std::vector<block_symbol> *labels;
std::vector<bound_minimal_symbol> minimal_symbols;
result->explicit_loc.func_name_match_type = fname_match_type;
if (source_filename != NULL)
{
- TRY
+ try
{
- *result->file_symtabs
+ result->file_symtabs
= symtabs_from_filename (source_filename, self->search_pspace);
}
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
source_file_not_found_error (source_filename);
}
- END_CATCH
result->explicit_loc.source_filename = xstrdup (source_filename);
}
else
{
/* A NULL entry means to use the default symtab. */
- result->file_symtabs->push_back (nullptr);
+ result->file_symtabs.push_back (nullptr);
}
if (function_name != NULL)
{
+ std::vector<block_symbol> symbols;
+
find_linespec_symbols (self, result->file_symtabs,
function_name, fname_match_type,
&symbols, &minimal_symbols);
result->explicit_loc.source_filename);
result->explicit_loc.function_name = xstrdup (function_name);
- result->function_symbols
- = new std::vector<block_symbol> (std::move (symbols));
- result->minimal_symbols
- = new std::vector<bound_minimal_symbol> (std::move (minimal_symbols));
+ result->function_symbols = std::move (symbols);
+ result->minimal_symbols = std::move (minimal_symbols);
}
if (label_name != NULL)
{
- labels = find_label_symbols (self, result->function_symbols,
- &symbols, label_name);
+ std::vector<block_symbol> symbols;
+ std::vector<block_symbol> labels
+ = find_label_symbols (self, result->function_symbols,
+ &symbols, label_name);
- if (labels == NULL)
+ if (labels.empty ())
undefined_label_error (result->explicit_loc.function_name,
label_name);
result->explicit_loc.label_name = xstrdup (label_name);
result->labels.label_symbols = labels;
- result->labels.function_symbols
- = new std::vector<block_symbol> (std::move (symbols));
+ result->labels.function_symbols = std::move (symbols);
}
if (line_offset.sign != LINE_OFFSET_UNKNOWN)
static std::vector<symtab_and_line>
convert_explicit_location_to_sals (struct linespec_state *self,
- linespec_p result,
+ linespec *result,
const struct explicit_location *explicit_loc)
{
convert_explicit_location_to_linespec (self, result,
label_name_spec -> STRING
function_name_spec -> STRING
offset_spec -> NUMBER
- -> '+' NUMBER
+ -> '+' NUMBER
-> '-' NUMBER
This may all be followed by several keywords such as "if EXPR",
if no file is validly specified. Callers must check that.
Also, the line number returned may be invalid. */
-/* Parse the linespec in ARG. MATCH_TYPE indicates how function names
- should be matched. */
+/* Parse the linespec in ARG, which must not be nullptr. MATCH_TYPE
+ indicates how function names should be matched. */
static std::vector<symtab_and_line>
parse_linespec (linespec_parser *parser, const char *arg,
symbol_name_match_type match_type)
{
- linespec_token token;
- struct gdb_exception file_exception = exception_none;
+ gdb_assert (arg != nullptr);
+
+ struct gdb_exception file_exception;
/* A special case to start. It has become quite popular for
IDEs to work around bugs in the previous parser by quoting
parser->is_quote_enclosed = 0;
if (parser->completion_tracker == NULL
&& !is_ada_operator (arg)
+ && *arg != '\0'
&& strchr (linespec_quote_characters, *arg) != NULL)
{
- const char *end;
-
- end = skip_quote_char (arg + 1, *arg);
+ const char *end = skip_quote_char (arg + 1, *arg);
if (end != NULL && is_closing_quote_enclosed (end))
{
/* Here's the special case. Skip ARG past the initial
/* Start parsing. */
/* Get the first token. */
- token = linespec_lexer_consume_token (parser);
+ linespec_token token = linespec_lexer_consume_token (parser);
/* It must be either LSTOKEN_STRING or LSTOKEN_NUMBER. */
if (token.type == LSTOKEN_STRING && *LS_TOKEN_STOKEN (token).ptr == '$')
{
/* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB. */
if (parser->completion_tracker == NULL)
- PARSER_RESULT (parser)->file_symtabs->push_back (nullptr);
+ PARSER_RESULT (parser)->file_symtabs.push_back (nullptr);
/* User specified a convenience variable or history value. */
gdb::unique_xmalloc_ptr<char> var = copy_token_string (token);
gdb::unique_xmalloc_ptr<char> user_filename = copy_token_string (token);
/* Check if the input is a filename. */
- TRY
+ try
{
- *PARSER_RESULT (parser)->file_symtabs
+ PARSER_RESULT (parser)->file_symtabs
= symtabs_from_filename (user_filename.get (),
PARSER_STATE (parser)->search_pspace);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (gdb_exception_error &ex)
{
- file_exception = ex;
+ file_exception = std::move (ex);
}
- END_CATCH
if (file_exception.reason >= 0)
{
else
{
/* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB. */
- PARSER_RESULT (parser)->file_symtabs->push_back (nullptr);
+ PARSER_RESULT (parser)->file_symtabs.push_back (nullptr);
}
}
/* If the next token is not EOI, KEYWORD, or COMMA, issue an error. */
else
{
/* A NULL entry means to use GLOBAL_DEFAULT_SYMTAB. */
- PARSER_RESULT (parser)->file_symtabs->push_back (nullptr);
+ PARSER_RESULT (parser)->file_symtabs.push_back (nullptr);
}
/* Parse the rest of the linespec. */
linespec_parse_basic (parser);
if (parser->completion_tracker == NULL
- && PARSER_RESULT (parser)->function_symbols == NULL
- && PARSER_RESULT (parser)->labels.label_symbols == NULL
+ && PARSER_RESULT (parser)->function_symbols.empty ()
+ && PARSER_RESULT (parser)->labels.label_symbols.empty ()
&& PARSER_EXPLICIT (parser)->line_offset.sign == LINE_OFFSET_UNKNOWN
- && PARSER_RESULT (parser)->minimal_symbols == NULL)
+ && PARSER_RESULT (parser)->minimal_symbols.empty ())
{
/* The linespec didn't parse. Re-throw the file exception if
there was one. */
if (file_exception.reason < 0)
- throw_exception (file_exception);
+ throw_exception (std::move (file_exception));
/* Otherwise, the symbol is not found. */
symbol_not_found_error (PARSER_EXPLICIT (parser)->function_name,
struct linespec_result *canonical)
{
lexer.current.type = LSTOKEN_CONSUMED;
- PARSER_RESULT (this)->file_symtabs = new std::vector<symtab *> ();
PARSER_EXPLICIT (this)->func_name_match_type
= symbol_name_match_type::WILD;
PARSER_EXPLICIT (this)->line_offset.sign = LINE_OFFSET_UNKNOWN;
xfree (PARSER_EXPLICIT (this)->label_name);
xfree (PARSER_EXPLICIT (this)->function_name);
- delete PARSER_RESULT (this)->file_symtabs;
- delete PARSER_RESULT (this)->function_symbols;
- delete PARSER_RESULT (this)->minimal_symbols;
- delete PARSER_RESULT (this)->labels.label_symbols;
- delete PARSER_RESULT (this)->labels.function_symbols;
-
linespec_state_destructor (PARSER_STATE (this));
}
const char *label_name)
{
std::vector<block_symbol> label_function_symbols;
- std::vector<block_symbol> *labels
+ std::vector<block_symbol> labels
= find_label_symbols (PARSER_STATE (parser),
PARSER_RESULT (parser)->function_symbols,
&label_function_symbols,
label_name, true);
- if (labels != nullptr)
+ for (const auto &label : labels)
{
- for (const auto &label : *labels)
- {
- char *match = xstrdup (SYMBOL_SEARCH_NAME (label.symbol));
- tracker.add_completion (gdb::unique_xmalloc_ptr<char> (match));
- }
- delete labels;
+ char *match = xstrdup (label.symbol->search_name ());
+ tracker.add_completion (gdb::unique_xmalloc_ptr<char> (match));
}
}
line_offset unknown_offset = { 0, LINE_OFFSET_UNKNOWN };
- TRY
+ try
{
convert_explicit_location_to_linespec (PARSER_STATE (&parser),
PARSER_RESULT (&parser),
func_name_match_type,
NULL, unknown_offset);
}
- CATCH (ex, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &ex)
{
return;
}
- END_CATCH
complete_label (tracker, &parser, label_name);
}
/* Parse as much as possible. parser.completion_word will hold
furthest completion point we managed to parse to. */
- TRY
+ try
{
parse_linespec (&parser, text, match_type);
}
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
}
- END_CATCH
if (parser.completion_quote_char != '\0'
&& parser.completion_quote_end != NULL
func_name, match_type,
&function_symbols, &minimal_symbols);
- PARSER_RESULT (&parser)->function_symbols
- = new std::vector<block_symbol> (std::move (function_symbols));
- PARSER_RESULT (&parser)->minimal_symbols
- = new std::vector<bound_minimal_symbol> (std::move (minimal_symbols));
+ PARSER_RESULT (&parser)->function_symbols = std::move (function_symbols);
+ PARSER_RESULT (&parser)->minimal_symbols = std::move (minimal_symbols);
complete_label (tracker, &parser, parser.completion_word);
}
case LINESPEC_LOCATION:
{
PARSER_STATE (parser)->is_linespec = 1;
- TRY
+ try
{
const linespec_location *ls = get_linespec_location (location);
result = parse_linespec (parser,
ls->spec_string, ls->match_type);
}
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
- throw_exception (except);
+ throw;
}
- END_CATCH
}
break;
/* See linespec.h. */
void
-decode_line_full (const struct event_location *location, int flags,
+decode_line_full (struct event_location *location, int flags,
struct program_space *search_pspace,
struct symtab *default_symtab,
int default_line, struct linespec_result *canonical,
location);
state = PARSER_STATE (&parser);
+ if (result.size () == 0)
+ throw_error (NOT_SUPPORTED_ERROR, _("Location %s not available"),
+ event_location_to_string (location));
+
gdb_assert (result.size () == 1 || canonical->pre_expanded);
canonical->pre_expanded = 1;
? decode_line_1 (location.get (), flags, NULL,
get_last_displayed_symtab (),
get_last_displayed_line ())
- : decode_line_1 (location.get (), flags, NULL,
- (struct symtab *) NULL, 0));
+ : decode_line_1 (location.get (), flags, NULL, NULL, 0));
if (*string)
error (_("Junk at end of line specification: %s"), string);
\f
-/* First, some functions to initialize stuff at the beggining of the
+/* First, some functions to initialize stuff at the beginning of the
function. */
static void
if (*default_symtab == 0)
{
/* Use whatever we have for the default source line. We don't use
- get_current_or_default_symtab_and_line as it can recurse and call
+ get_current_or_default_symtab_and_line as it can recurse and call
us back! */
struct symtab_and_line cursal =
get_current_source_symtab_and_line ();
the existing C++ code to let the user choose one. */
static std::vector<symtab_and_line>
-decode_objc (struct linespec_state *self, linespec_p ls, const char *arg)
+decode_objc (struct linespec_state *self, linespec *ls, const char *arg)
{
struct collect_info info;
std::vector<const char *> symbol_names;
saved_arg[new_argptr - arg] = '\0';
ls->explicit_loc.function_name = xstrdup (saved_arg);
- ls->function_symbols
- = new std::vector<block_symbol> (std::move (symbols));
- ls->minimal_symbols
- = new std::vector<bound_minimal_symbol> (std::move (minimal_symbols));
+ ls->function_symbols = std::move (symbols);
+ ls->minimal_symbols = std::move (minimal_symbols);
values = convert_linespec_to_sals (self, ls);
if (self->canonical)
{
public:
decode_compound_collector ()
+ : m_unique_syms (htab_create_alloc (1, htab_hash_pointer,
+ htab_eq_pointer, NULL,
+ xcalloc, xfree))
{
- 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);
}
/* Return all symbols collected. */
private:
/* A hash table of all symbols we found. We use this to avoid
adding any symbol more than once. */
- htab_t m_unique_syms;
+ htab_up m_unique_syms;
/* The result vector. */
std::vector<block_symbol> m_symbols;
struct type *t;
struct symbol *sym = bsym->symbol;
- if (SYMBOL_CLASS (sym) != LOC_TYPEDEF)
+ if (sym->aclass () != LOC_TYPEDEF)
return true; /* Continue iterating. */
- t = SYMBOL_TYPE (sym);
+ t = sym->type ();
t = check_typedef (t);
- if (TYPE_CODE (t) != TYPE_CODE_STRUCT
- && TYPE_CODE (t) != TYPE_CODE_UNION
- && TYPE_CODE (t) != TYPE_CODE_NAMESPACE)
+ if (t->code () != TYPE_CODE_STRUCT
+ && t->code () != TYPE_CODE_UNION
+ && t->code () != TYPE_CODE_NAMESPACE)
return true; /* Continue iterating. */
- slot = htab_find_slot (m_unique_syms, sym, INSERT);
+ slot = htab_find_slot (m_unique_syms.get (), sym, INSERT);
if (!*slot)
{
*slot = sym;
static std::vector<block_symbol>
lookup_prefix_sym (struct linespec_state *state,
- std::vector<symtab *> *file_symtabs,
+ const std::vector<symtab *> &file_symtabs,
const char *class_name)
{
decode_compound_collector collector;
lookup_name_info lookup_name (class_name, symbol_name_match_type::FULL);
- for (const auto &elt : *file_symtabs)
+ for (const auto &elt : file_symtabs)
{
if (elt == nullptr)
{
{
/* Program spaces that are executing startup should have
been filtered out earlier. */
- gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
- set_current_program_space (SYMTAB_PSPACE (elt));
+ gdb_assert (!elt->pspace ()->executing_startup);
+ set_current_program_space (elt->pspace ());
iterate_over_file_blocks (elt, lookup_name, STRUCT_DOMAIN, collector);
iterate_over_file_blocks (elt, lookup_name, VAR_DOMAIN, collector);
}
{
uintptr_t uia, uib;
- uia = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (a.symbol));
- uib = (uintptr_t) SYMTAB_PSPACE (symbol_symtab (b.symbol));
+ uia = (uintptr_t) symbol_symtab (a.symbol)->pspace ();
+ uib = (uintptr_t) symbol_symtab (b.symbol)->pspace ();
if (uia < uib)
return true;
in SYMBOLS (for debug symbols) and MINSYMS (for minimal symbols). */
static void
-find_method (struct linespec_state *self, std::vector<symtab *> *file_symtabs,
+find_method (struct linespec_state *self,
+ const std::vector<symtab *> &file_symtabs,
const char *class_name, const char *method_name,
std::vector<block_symbol> *sym_classes,
std::vector<block_symbol> *symbols,
compare_symbols);
info.state = self;
- info.file_symtabs = file_symtabs;
+ info.file_symtabs = &file_symtabs;
info.result.symbols = symbols;
info.result.minimal_symbols = minsyms;
because we collect data across the program space before deciding
what to do. */
last_result_len = 0;
- unsigned int ix = 0;
for (const auto &elt : *sym_classes)
{
struct type *t;
struct program_space *pspace;
struct symbol *sym = elt.symbol;
+ unsigned int ix = &elt - &*sym_classes->begin ();
/* Program spaces that are executing startup should have
been filtered out earlier. */
- pspace = SYMTAB_PSPACE (symbol_symtab (sym));
+ pspace = symbol_symtab (sym)->pspace ();
gdb_assert (!pspace->executing_startup);
set_current_program_space (pspace);
- t = check_typedef (SYMBOL_TYPE (sym));
- find_methods (t, SYMBOL_LANGUAGE (sym),
+ t = check_typedef (sym->type ());
+ find_methods (t, sym->language (),
method_name, &result_names, &superclass_vec);
/* Handle all items from a single program space at once; and be
sure not to miss the last batch. */
if (ix == sym_classes->size () - 1
|| (pspace
- != SYMTAB_PSPACE (symbol_symtab (sym_classes->at (ix + 1).symbol))))
+ != symbol_symtab (sym_classes->at (ix + 1).symbol)->pspace ()))
{
/* If we did not find a direct implementation anywhere in
this program space, consider superclasses. */
if (result_names.size () == last_result_len)
find_superclass_methods (std::move (superclass_vec), method_name,
- SYMBOL_LANGUAGE (sym), &result_names);
+ sym->language (), &result_names);
/* We have a list of candidate symbol names, so now we
iterate over the symbol tables looking for all
superclass_vec.clear ();
last_result_len = result_names.size ();
- ++ix;
}
}
{
public:
symtab_collector ()
+ : m_symtab_table (htab_create (1, htab_hash_pointer, htab_eq_pointer,
+ 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. */
std::vector<symtab *> m_symtabs;
/* This is used to ensure the symtabs are unique. */
- htab_t m_symtab_table;
+ htab_up m_symtab_table;
};
bool
{
void **slot;
- slot = htab_find_slot (m_symtab_table, symtab, INSERT);
+ slot = htab_find_slot (m_symtab_table.get (), symtab, INSERT);
if (!*slot)
{
*slot = symtab;
/* Find that file's data. */
if (search_pspace == NULL)
{
- struct program_space *pspace;
-
- ALL_PSPACES (pspace)
- {
+ for (struct program_space *pspace : program_spaces)
+ {
if (pspace->executing_startup)
continue;
static void
find_function_symbols (struct linespec_state *state,
- std::vector<symtab *> *file_symtabs, const char *name,
+ const std::vector<symtab *> &file_symtabs, const char *name,
symbol_name_match_type name_match_type,
std::vector<block_symbol> *symbols,
std::vector<bound_minimal_symbol> *minsyms)
info.state = state;
info.result.symbols = symbols;
info.result.minimal_symbols = minsyms;
- info.file_symtabs = file_symtabs;
+ info.file_symtabs = &file_symtabs;
/* Try NAME as an Objective-C selector. */
find_imps (name, &symbol_names);
static void
find_linespec_symbols (struct linespec_state *state,
- std::vector<symtab *> *file_symtabs,
+ const std::vector<symtab *> &file_symtabs,
const char *lookup_name,
symbol_name_match_type name_match_type,
std::vector <block_symbol> *symbols,
std::vector<bound_minimal_symbol> *minsyms)
{
- std::string canon = cp_canonicalize_string_no_typedefs (lookup_name);
- if (!canon.empty ())
- lookup_name = canon.c_str ();
+ gdb::unique_xmalloc_ptr<char> canon
+ = cp_canonicalize_string_no_typedefs (lookup_name);
+ if (canon != nullptr)
+ lookup_name = canon.get ();
/* It's important to not call expand_symtabs_matching unnecessarily
as it can really slow things down (by unnecessarily expanding
if (!classes.empty ())
{
/* Now locate a list of suitable methods named METHOD. */
- TRY
+ try
{
find_method (state, file_symtabs,
klass.c_str (), method.c_str (),
/* If successful, we're done. If NOT_FOUND_ERROR
was not thrown, rethrow the exception that we did get. */
- CATCH (except, RETURN_MASK_ERROR)
+ catch (const gdb_exception_error &except)
{
if (except.error != NOT_FOUND_ERROR)
- throw_exception (except);
+ throw;
}
- END_CATCH
}
}
}
ALL_BLOCK_SYMBOLS (block, iter, sym)
{
- if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
- SYMBOL_DOMAIN (sym), LABEL_DOMAIN)
- && cmp (SYMBOL_SEARCH_NAME (sym), name, name_len) == 0)
+ if (symbol_matches_domain (sym->language (),
+ sym->domain (), LABEL_DOMAIN)
+ && cmp (sym->search_name (), name, name_len) == 0)
{
result->push_back ({sym, block});
label_funcs_ret->push_back ({fn_sym, block});
}
}
-/* Return all labels that match name NAME in FUNCTION_SYMBOLS or NULL
- if no matches were found.
+/* Return all labels that match name NAME in FUNCTION_SYMBOLS.
Return the actual function symbol in which the label was found in
LABEL_FUNC_RET. If COMPLETION_MODE is true, then NAME is
exactly NAME match. */
-static std::vector<block_symbol> *
+static std::vector<block_symbol>
find_label_symbols (struct linespec_state *self,
- std::vector<block_symbol> *function_symbols,
+ const std::vector<block_symbol> &function_symbols,
std::vector<block_symbol> *label_funcs_ret,
const char *name,
bool completion_mode)
struct symbol *fn_sym;
std::vector<block_symbol> result;
- if (function_symbols == NULL)
+ if (function_symbols.empty ())
{
set_current_program_space (self->program_space);
block = get_current_search_block ();
block && !BLOCK_FUNCTION (block);
block = BLOCK_SUPERBLOCK (block))
;
+
if (!block)
- return NULL;
+ return {};
+
fn_sym = BLOCK_FUNCTION (block);
find_label_symbols_in_block (block, name, fn_sym, completion_mode,
}
else
{
- for (const auto &elt : *function_symbols)
+ for (const auto &elt : function_symbols)
{
fn_sym = elt.symbol;
- set_current_program_space (SYMTAB_PSPACE (symbol_symtab (fn_sym)));
+ set_current_program_space (symbol_symtab (fn_sym)->pspace ());
block = SYMBOL_BLOCK_VALUE (fn_sym);
find_label_symbols_in_block (block, name, fn_sym, completion_mode,
}
}
- if (!result.empty ())
- return new std::vector<block_symbol> (std::move (result));
- return nullptr;
+ return result;
}
\f
static std::vector<symtab_and_line>
decode_digits_list_mode (struct linespec_state *self,
- linespec_p ls,
+ linespec *ls,
struct symtab_and_line val)
{
gdb_assert (self->list_mode);
std::vector<symtab_and_line> values;
- for (const auto &elt : *ls->file_symtabs)
+ for (const auto &elt : ls->file_symtabs)
{
/* The logic above should ensure this. */
gdb_assert (elt != NULL);
- set_current_program_space (SYMTAB_PSPACE (elt));
+ set_current_program_space (elt->pspace ());
/* Simplistic search just for the list command. */
val.symtab = find_line_symtab (elt, val.line, NULL, NULL);
if (val.symtab == NULL)
val.symtab = elt;
- val.pspace = SYMTAB_PSPACE (elt);
+ val.pspace = elt->pspace ();
val.pc = 0;
- val.explicit_line = 1;
+ val.explicit_line = true;
add_sal_to_sals (self, &values, &val, NULL, 0);
}
return values;
}
-/* A helper for create_sals_line_offset that iterates over the symtabs,
- adding lines to the VEC. */
+/* A helper for create_sals_line_offset that iterates over the symtabs
+ associated with LS and returns a vector of corresponding symtab_and_line
+ structures. */
static std::vector<symtab_and_line>
decode_digits_ordinary (struct linespec_state *self,
- linespec_p ls,
+ linespec *ls,
int line,
struct linetable_entry **best_entry)
{
std::vector<symtab_and_line> sals;
- for (const auto &elt : *ls->file_symtabs)
+ for (const auto &elt : ls->file_symtabs)
{
std::vector<CORE_ADDR> pcs;
/* The logic above should ensure this. */
gdb_assert (elt != NULL);
- set_current_program_space (SYMTAB_PSPACE (elt));
+ set_current_program_space (elt->pspace ());
pcs = find_pcs_for_symtab_line (elt, line, best_entry);
for (CORE_ADDR pc : pcs)
{
symtab_and_line sal;
- sal.pspace = SYMTAB_PSPACE (elt);
+ sal.pspace = elt->pspace ();
sal.symtab = elt;
sal.line = line;
+ sal.explicit_line = true;
sal.pc = pc;
sals.push_back (std::move (sal));
}
sscanf ((variable[1] == '$') ? variable + 2 : variable + 1, "%d", &index);
val_history
= access_value_history ((variable[1] == '$') ? -index : index);
- if (TYPE_CODE (value_type (val_history)) != TYPE_CODE_INT)
+ if (value_type (val_history)->code () != TYPE_CODE_INT)
error (_("History values used in line "
"specs must have integer values."));
offset.offset = value_as_long (val_history);
if (is_function)
{
- const char *msym_name = MSYMBOL_LINKAGE_NAME (msymbol);
+ const char *msym_name = msymbol->linkage_name ();
if (MSYMBOL_TYPE (msymbol) == mst_text_gnu_ifunc
|| MSYMBOL_TYPE (msymbol) == mst_data_gnu_ifunc)
sal.pspace = current_program_space;
}
- sal.section = MSYMBOL_OBJ_SECTION (objfile, msymbol);
+ sal.section = msymbol->obj_section (objfile);
if (maybe_add_address (self->addr_set, objfile->pspace, sal.pc))
- add_sal_to_sals (self, result, &sal, MSYMBOL_NATURAL_NAME (msymbol), 0);
-}
-
-/* A helper function to classify a minimal_symbol_type according to
- priority. */
-
-static int
-classify_mtype (enum minimal_symbol_type t)
-{
- switch (t)
- {
- case mst_file_text:
- case mst_file_data:
- case mst_file_bss:
- /* Intermediate priority. */
- return 1;
-
- case mst_solib_trampoline:
- /* Lowest priority. */
- return 2;
-
- default:
- /* Highest priority. */
- return 0;
- }
-}
-
-/* Callback for std::sort that sorts symbols by priority. */
-
-static bool
-compare_msyms (const bound_minimal_symbol &a, const bound_minimal_symbol &b)
-{
- enum minimal_symbol_type ta = MSYMBOL_TYPE (a.minsym);
- enum minimal_symbol_type tb = MSYMBOL_TYPE (b.minsym);
-
- return classify_mtype (ta) < classify_mtype (tb);
+ add_sal_to_sals (self, result, &sal, msymbol->natural_name (), 0);
}
/* Helper for search_minsyms_for_name that adds the symbol to the
if (!list_mode && !msymbol_is_function (objfile, minsym))
return;
- struct bound_minimal_symbol mo = {minsym, objfile};
- msyms->push_back (mo);
+ msyms->emplace_back (minsym, objfile);
return;
}
if (symtab == NULL)
{
- struct program_space *pspace;
-
- ALL_PSPACES (pspace)
- {
- struct objfile *objfile;
-
- if (search_pspace != NULL && search_pspace != pspace)
- continue;
- if (pspace->executing_startup)
- continue;
+ for (struct program_space *pspace : program_spaces)
+ {
+ if (search_pspace != NULL && search_pspace != pspace)
+ continue;
+ if (pspace->executing_startup)
+ continue;
- set_current_program_space (pspace);
+ set_current_program_space (pspace);
- ALL_OBJFILES (objfile)
- {
- iterate_over_minimal_symbols (objfile, name,
- [&] (struct minimal_symbol *msym)
- {
- add_minsym (msym, objfile, nullptr,
- info->state->list_mode,
- &minsyms);
- return false;
- });
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ iterate_over_minimal_symbols (objfile, name,
+ [&] (struct minimal_symbol *msym)
+ {
+ add_minsym (msym, objfile, nullptr,
+ info->state->list_mode,
+ &minsyms);
+ return false;
+ });
+ }
}
- }
}
else
{
- if (search_pspace == NULL || SYMTAB_PSPACE (symtab) == search_pspace)
+ if (search_pspace == NULL || symtab->pspace () == search_pspace)
{
- set_current_program_space (SYMTAB_PSPACE (symtab));
+ set_current_program_space (symtab->pspace ());
iterate_over_minimal_symbols
- (SYMTAB_OBJFILE (symtab), name,
+ (symtab->objfile (), name,
[&] (struct minimal_symbol *msym)
{
- add_minsym (msym, SYMTAB_OBJFILE (symtab), symtab,
+ add_minsym (msym, symtab->objfile (), symtab,
info->state->list_mode, &minsyms);
return false;
});
}
}
- if (!minsyms.empty ())
+ /* Return true if TYPE is a static symbol. */
+ auto msymbol_type_is_static = [] (enum minimal_symbol_type type)
{
- int classification;
+ switch (type)
+ {
+ case mst_file_text:
+ case mst_file_data:
+ case mst_file_bss:
+ return true;
+ default:
+ return false;
+ }
+ };
- std::sort (minsyms.begin (), minsyms.end (), compare_msyms);
+ /* Add minsyms to the result set, but filter out trampoline symbols
+ if we also found extern symbols with the same name. I.e., don't
+ set a breakpoint on both '<foo@plt>' and 'foo', assuming that
+ 'foo' is the symbol that the plt resolves to. */
+ for (const bound_minimal_symbol &item : minsyms)
+ {
+ bool skip = false;
+ if (MSYMBOL_TYPE (item.minsym) == mst_solib_trampoline)
+ {
+ for (const bound_minimal_symbol &item2 : minsyms)
+ {
+ if (&item2 == &item)
+ continue;
- /* 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. */
- classification = classify_mtype (MSYMBOL_TYPE (minsyms[0].minsym));
+ /* Trampoline symbols can only jump to exported
+ symbols. */
+ if (msymbol_type_is_static (MSYMBOL_TYPE (item2.minsym)))
+ continue;
- for (const bound_minimal_symbol &item : minsyms)
- {
- if (classify_mtype (MSYMBOL_TYPE (item.minsym)) != classification)
- break;
+ if (strcmp (item.minsym->linkage_name (),
+ item2.minsym->linkage_name ()) != 0)
+ continue;
- info->result.minimal_symbols->push_back (item);
+ /* Found a global minsym with the same name as the
+ trampoline. Don't create a location for this
+ trampoline. */
+ skip = true;
+ break;
+ }
}
+
+ if (!skip)
+ info->result.minimal_symbols->push_back (item);
}
}
{ return info->add_symbol (bsym); });
search_minsyms_for_name (info, lookup_name, pspace, NULL);
}
- else if (pspace == NULL || pspace == SYMTAB_PSPACE (elt))
+ else if (pspace == NULL || pspace == elt->pspace ())
{
int prev_len = info->result.symbols->size ();
/* Program spaces that are executing startup should have
been filtered out earlier. */
- gdb_assert (!SYMTAB_PSPACE (elt)->executing_startup);
- set_current_program_space (SYMTAB_PSPACE (elt));
+ gdb_assert (!elt->pspace ()->executing_startup);
+ set_current_program_space (elt->pspace ());
iterate_over_file_blocks (elt, lookup_name, VAR_DOMAIN,
[&] (block_symbol *bsym)
{ return info->add_symbol (bsym); });
which we don't have debug info. Check for a minimal symbol in
this case. */
if (prev_len == info->result.symbols->size ()
- && elt->language == language_asm)
+ && elt->language () == language_asm)
search_minsyms_for_name (info, lookup_name, pspace, elt);
}
}
symbol_to_sal (struct symtab_and_line *result,
int funfirstline, struct symbol *sym)
{
- if (SYMBOL_CLASS (sym) == LOC_BLOCK)
+ if (sym->aclass () == LOC_BLOCK)
{
*result = find_function_start_sal (sym, funfirstline);
return 1;
}
else
{
- if (SYMBOL_CLASS (sym) == LOC_LABEL && SYMBOL_VALUE_ADDRESS (sym) != 0)
+ if (sym->aclass () == LOC_LABEL && SYMBOL_VALUE_ADDRESS (sym) != 0)
{
*result = {};
result->symtab = symbol_symtab (sym);
result->symbol = sym;
- result->line = SYMBOL_LINE (sym);
+ result->line = sym->line ();
result->pc = SYMBOL_VALUE_ADDRESS (sym);
- result->pspace = SYMTAB_PSPACE (result->symtab);
+ result->pspace = result->symtab->pspace ();
result->explicit_pc = 1;
return 1;
}
{
/* Nothing. */
}
- else if (SYMBOL_LINE (sym) != 0)
+ else if (sym->line () != 0)
{
/* We know its line number. */
*result = {};
result->symtab = symbol_symtab (sym);
result->symbol = sym;
- result->line = SYMBOL_LINE (sym);
+ result->line = sym->line ();
result->pc = SYMBOL_VALUE_ADDRESS (sym);
- result->pspace = SYMTAB_PSPACE (result->symtab);
+ result->pspace = result->symtab->pspace ();
return 1;
}
}