/* Parser for linespec for the GNU debugger, GDB.
- Copyright (C) 1986-2020 Free Software Foundation, Inc.
+ Copyright (C) 1986-2022 Free Software Foundation, Inc.
This file is part of GDB.
#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)
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 program_space *pspace;
+ for (struct program_space *pspace : program_spaces)
+ {
+ if (search_pspace != NULL && search_pspace != pspace)
+ continue;
+ if (pspace->executing_startup)
+ continue;
- ALL_PSPACES (pspace)
- {
- if (search_pspace != NULL && search_pspace != pspace)
- continue;
- if (pspace->executing_startup)
- continue;
+ set_current_program_space (pspace);
- set_current_program_space (pspace);
+ for (objfile *objfile : current_program_space->objfiles ())
+ {
+ objfile->expand_symtabs_matching (NULL, &lookup_name, NULL, NULL,
+ (SEARCH_GLOBAL_BLOCK
+ | SEARCH_STATIC_BLOCK),
+ UNDEF_DOMAIN,
+ search_domain);
- for (objfile *objfile : current_program_space->objfiles ())
- {
- if (objfile->sf)
- objfile->sf->qf->expand_symtabs_matching (objfile,
- NULL,
- &lookup_name,
- NULL, NULL,
- search_domain);
-
- for (compunit_symtab *cu : objfile->compunits ())
- {
- struct symtab *symtab = COMPUNIT_FILETABS (cu);
+ for (compunit_symtab *cu : objfile->compunits ())
+ {
+ struct symtab *symtab = cu->primary_filetab ();
- iterate_over_file_blocks (symtab, lookup_name, name_domain,
- callback);
+ iterate_over_file_blocks (symtab, lookup_name, name_domain,
+ callback);
- if (include_inline)
- {
- const struct block *block;
- int i;
+ if (include_inline)
+ {
+ const struct block *block;
+ int i;
- for (i = FIRST_LOCAL_BLOCK;
- i < BLOCKVECTOR_NBLOCKS (SYMTAB_BLOCKVECTOR (symtab));
- i++)
- {
- block = BLOCKVECTOR_BLOCK (SYMTAB_BLOCKVECTOR (symtab), i);
- state->language->la_iterate_over_symbols
- (block, 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;
- });
- }
- }
- }
- }
- }
+ 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
{
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;
{
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 ();
+ 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)
{
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);
- *ls->file_symtabs
+ ls->file_symtabs
= collect_symtabs_from_filename (self->default_symtab->filename,
self->search_pspace);
use_default = 1;
/* 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))
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 (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;
{
try
{
- *result->file_symtabs
+ result->file_symtabs
= symtabs_from_filename (source_filename, self->search_pspace);
}
catch (const gdb_exception_error &except)
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;
+ gdb_assert (arg != nullptr);
+
struct gdb_exception file_exception;
/* A special case to start. It has become quite popular for
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);
/* Check if the input is a filename. */
try
{
- *PARSER_RESULT (parser)->file_symtabs
+ PARSER_RESULT (parser)->file_symtabs
= symtabs_from_filename (user_filename.get (),
PARSER_STATE (parser)->search_pspace);
}
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. */
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 (label.symbol->search_name ());
- 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));
}
}
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);
}
/* 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;
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));
+ t = check_typedef (sym->type ());
find_methods (t, sym->language (),
method_name, &result_names, &superclass_vec);
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. */
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
ALL_BLOCK_SYMBOLS (block, iter, sym)
{
if (symbol_matches_domain (sym->language (),
- SYMBOL_DOMAIN (sym), LABEL_DOMAIN)
+ sym->domain (), LABEL_DOMAIN)
&& cmp (sym->search_name (), name, name_len) == 0)
{
result->push_back ({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 = true;
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;
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);
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 (), 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);
-}
-
/* Helper for search_minsyms_for_name that adds the symbol to the
result. */
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)
- {
- 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);
- 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;
- });
- }
- }
+ 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;
}
}