Eliminate the two-level data structures behind location_specs

Currently, there's the location_spec hierarchy, and then some
location_spec subclasses have their own struct type holding all their
data fields.

I.e., there is this:

 location_spec
   explicit_location_spec
   linespec_location_spec
   address_location_spec
   probe_location_spec

and then these separate types:

  explicit_location
  linespec_location

where:

  explicit_location_spec
     has-a explicit_location
  linespec_location_spec
     has-a linespec_location

This patch eliminates explicit_location and linespec_location,
inlining their members in the corresponding location_spec type.

The location_spec subclasses were the ones currently defined in
location.c, so they are moved to the header.  Since the definitions of
the classes are now visible, we no longer need location_spec_deleter.

Some constructors that are used for cloning location_specs, like:

  explicit explicit_location_spec (const struct explicit_location *loc)

... were converted to proper copy ctors.

In the process, initialize_explicit_location is eliminated, and some
functions that returned the "data type behind a locspec", like
get_linespec_location are converted to downcast functions, like
as_linespec_location_spec.

Change-Id: Ia31ccef9382b25a52b00fa878c8df9b8cf2a6c5a
This commit is contained in:
Pedro Alves 2022-05-27 13:13:41 +01:00
parent 264f98902f
commit 40d97ee21f
9 changed files with 434 additions and 488 deletions

View file

@ -225,12 +225,9 @@ exception_catchpoint::re_set ()
catchpoint mode. */ catchpoint mode. */
try try
{ {
struct explicit_location explicit_loc; location_spec_up locspec
= (new_explicit_location_spec_function
initialize_explicit_location (&explicit_loc); (exception_functions[kind].function));
explicit_loc.function_name
= ASTRDUP (exception_functions[kind].function);
location_spec_up locspec = new_explicit_location_spec (&explicit_loc);
sals = this->decode_location_spec (locspec.get (), filter_pspace); sals = this->decode_location_spec (locspec.get (), filter_pspace);
} }
catch (const gdb_exception_error &ex) catch (const gdb_exception_error &ex)

View file

@ -3364,7 +3364,6 @@ create_overlay_event_breakpoint (void)
struct breakpoint *b; struct breakpoint *b;
struct breakpoint_objfile_data *bp_objfile_data; struct breakpoint_objfile_data *bp_objfile_data;
CORE_ADDR addr; CORE_ADDR addr;
struct explicit_location explicit_loc;
bp_objfile_data = get_breakpoint_objfile_data (objfile); bp_objfile_data = get_breakpoint_objfile_data (objfile);
@ -3388,9 +3387,7 @@ create_overlay_event_breakpoint (void)
addr = bp_objfile_data->overlay_msym.value_address (); addr = bp_objfile_data->overlay_msym.value_address ();
b = create_internal_breakpoint (objfile->arch (), addr, b = create_internal_breakpoint (objfile->arch (), addr,
bp_overlay_event); bp_overlay_event);
initialize_explicit_location (&explicit_loc); b->locspec = new_explicit_location_spec_function (func_name);
explicit_loc.function_name = ASTRDUP (func_name);
b->locspec = new_explicit_location_spec (&explicit_loc);
if (overlay_debugging == ovly_auto) if (overlay_debugging == ovly_auto)
{ {
@ -3473,7 +3470,6 @@ create_longjmp_master_breakpoint_names (objfile *objfile)
struct breakpoint *b; struct breakpoint *b;
const char *func_name; const char *func_name;
CORE_ADDR addr; CORE_ADDR addr;
struct explicit_location explicit_loc;
if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym)) if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym))
continue; continue;
@ -3495,9 +3491,7 @@ create_longjmp_master_breakpoint_names (objfile *objfile)
addr = bp_objfile_data->longjmp_msym[i].value_address (); addr = bp_objfile_data->longjmp_msym[i].value_address ();
b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master); b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master);
initialize_explicit_location (&explicit_loc); b->locspec = new_explicit_location_spec_function (func_name);
explicit_loc.function_name = ASTRDUP (func_name);
b->locspec = new_explicit_location_spec (&explicit_loc);
b->enable_state = bp_disabled; b->enable_state = bp_disabled;
installed_bp++; installed_bp++;
} }
@ -3553,7 +3547,6 @@ create_std_terminate_master_breakpoint (void)
{ {
struct breakpoint *b; struct breakpoint *b;
struct breakpoint_objfile_data *bp_objfile_data; struct breakpoint_objfile_data *bp_objfile_data;
struct explicit_location explicit_loc;
bp_objfile_data = get_breakpoint_objfile_data (objfile); bp_objfile_data = get_breakpoint_objfile_data (objfile);
@ -3578,9 +3571,7 @@ create_std_terminate_master_breakpoint (void)
addr = bp_objfile_data->terminate_msym.value_address (); addr = bp_objfile_data->terminate_msym.value_address ();
b = create_internal_breakpoint (objfile->arch (), addr, b = create_internal_breakpoint (objfile->arch (), addr,
bp_std_terminate_master); bp_std_terminate_master);
initialize_explicit_location (&explicit_loc); b->locspec = new_explicit_location_spec_function (func_name);
explicit_loc.function_name = ASTRDUP (func_name);
b->locspec = new_explicit_location_spec (&explicit_loc);
b->enable_state = bp_disabled; b->enable_state = bp_disabled;
} }
} }
@ -3648,7 +3639,6 @@ create_exception_master_breakpoint_hook (objfile *objfile)
struct gdbarch *gdbarch; struct gdbarch *gdbarch;
struct breakpoint_objfile_data *bp_objfile_data; struct breakpoint_objfile_data *bp_objfile_data;
CORE_ADDR addr; CORE_ADDR addr;
struct explicit_location explicit_loc;
bp_objfile_data = get_breakpoint_objfile_data (objfile); bp_objfile_data = get_breakpoint_objfile_data (objfile);
@ -3675,9 +3665,7 @@ create_exception_master_breakpoint_hook (objfile *objfile)
addr = gdbarch_convert_from_func_ptr_addr addr = gdbarch_convert_from_func_ptr_addr
(gdbarch, addr, current_inferior ()->top_target ()); (gdbarch, addr, current_inferior ()->top_target ());
b = create_internal_breakpoint (gdbarch, addr, bp_exception_master); b = create_internal_breakpoint (gdbarch, addr, bp_exception_master);
initialize_explicit_location (&explicit_loc); b->locspec = new_explicit_location_spec_function (func_name);
explicit_loc.function_name = ASTRDUP (func_name);
b->locspec = new_explicit_location_spec (&explicit_loc);
b->enable_state = bp_disabled; b->enable_state = bp_disabled;
return true; return true;
@ -8467,7 +8455,7 @@ parse_breakpoint_sals (location_spec *locspec,
if (location_spec_type (locspec) == LINESPEC_LOCATION_SPEC) if (location_spec_type (locspec) == LINESPEC_LOCATION_SPEC)
{ {
const char *spec = get_linespec_location (locspec)->spec_string; const char *spec = as_linespec_location_spec (locspec)->spec_string;
if (spec == NULL) if (spec == NULL)
{ {
@ -8518,7 +8506,7 @@ parse_breakpoint_sals (location_spec *locspec,
const char *spec = NULL; const char *spec = NULL;
if (location_spec_type (locspec) == LINESPEC_LOCATION_SPEC) if (location_spec_type (locspec) == LINESPEC_LOCATION_SPEC)
spec = get_linespec_location (locspec)->spec_string; spec = as_linespec_location_spec (locspec)->spec_string;
if (!cursal.symtab if (!cursal.symtab
|| (spec != NULL || (spec != NULL
@ -12005,7 +11993,7 @@ strace_marker_create_sals_from_location_spec (location_spec *locspec,
struct linespec_sals lsal; struct linespec_sals lsal;
const char *arg_start, *arg; const char *arg_start, *arg;
arg = arg_start = get_linespec_location (locspec)->spec_string; arg = arg_start = as_linespec_location_spec (locspec)->spec_string;
lsal.sals = decode_static_tracepoint_spec (&arg); lsal.sals = decode_static_tracepoint_spec (&arg);
std::string str (arg_start, arg - arg_start); std::string str (arg_start, arg - arg_start);
@ -12073,7 +12061,7 @@ std::vector<symtab_and_line>
static_marker_tracepoint::decode_location_spec (location_spec *locspec, static_marker_tracepoint::decode_location_spec (location_spec *locspec,
program_space *search_pspace) program_space *search_pspace)
{ {
const char *s = get_linespec_location (locspec)->spec_string; const char *s = as_linespec_location_spec (locspec)->spec_string;
std::vector<symtab_and_line> sals = decode_static_tracepoint_spec (&s); std::vector<symtab_and_line> sals = decode_static_tracepoint_spec (&s);
if (sals.size () > static_trace_marker_id_idx) if (sals.size () > static_trace_marker_id_idx)
@ -12381,7 +12369,6 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
struct symbol *sym; struct symbol *sym;
struct static_tracepoint_marker *tpmarker; struct static_tracepoint_marker *tpmarker;
struct ui_out *uiout = current_uiout; struct ui_out *uiout = current_uiout;
struct explicit_location explicit_loc;
tpmarker = &markers[0]; tpmarker = &markers[0];
@ -12418,13 +12405,14 @@ update_static_tracepoint (struct breakpoint *b, struct symtab_and_line sal)
b->loc->line_number = sal2.line; b->loc->line_number = sal2.line;
b->loc->symtab = sym != NULL ? sal2.symtab : NULL; b->loc->symtab = sym != NULL ? sal2.symtab : NULL;
b->locspec.reset (nullptr); std::unique_ptr<explicit_location_spec> els
initialize_explicit_location (&explicit_loc); (new explicit_location_spec ());
explicit_loc.source_filename els->source_filename
= ASTRDUP (symtab_to_filename_for_display (sal2.symtab)); = xstrdup (symtab_to_filename_for_display (sal2.symtab));
explicit_loc.line_offset.offset = b->loc->line_number; els->line_offset.offset = b->loc->line_number;
explicit_loc.line_offset.sign = LINE_OFFSET_NONE; els->line_offset.sign = LINE_OFFSET_NONE;
b->locspec = new_explicit_location_spec (&explicit_loc);
b->locspec = std::move (els);
/* Might be nice to check if function changed, and warn if /* Might be nice to check if function changed, and warn if
so. */ so. */

View file

@ -712,8 +712,8 @@ collect_explicit_location_matches (completion_tracker &tracker,
const char *word, const char *word,
const struct language_defn *language) const struct language_defn *language)
{ {
const struct explicit_location *explicit_loc const explicit_location_spec *explicit_loc
= get_explicit_location (locspec); = as_explicit_location_spec (locspec);
/* True if the option expects an argument. */ /* True if the option expects an argument. */
bool needs_arg = true; bool needs_arg = true;
@ -1008,7 +1008,7 @@ location_completer (struct cmd_list_element *ignore,
text = copy; text = copy;
symbol_name_match_type match_type symbol_name_match_type match_type
= get_explicit_location (locspec.get ())->func_name_match_type; = as_explicit_location_spec (locspec.get ())->func_name_match_type;
complete_address_and_linespec_locations (tracker, text, match_type); complete_address_and_linespec_locations (tracker, text, match_type);
} }
} }

View file

@ -94,8 +94,8 @@ struct address_entry
struct linespec struct linespec
{ {
/* An explicit location describing the SaLs. */ /* An explicit location spec describing the SaLs. */
struct explicit_location explicit_loc {}; explicit_location_spec explicit_loc;
/* The list of symtabs to search to which to limit the search. /* The list of symtabs to search to which to limit the search.
@ -342,8 +342,8 @@ struct linespec_parser
struct completion_tracker *completion_tracker = nullptr; struct completion_tracker *completion_tracker = nullptr;
}; };
/* A convenience macro for accessing the explicit location result of /* A convenience macro for accessing the explicit location spec result
the parser. */ of the parser. */
#define PARSER_EXPLICIT(PPTR) (&PARSER_RESULT ((PPTR))->explicit_loc) #define PARSER_EXPLICIT(PPTR) (&PARSER_RESULT ((PPTR))->explicit_loc)
/* Prototypes for local functions. */ /* Prototypes for local functions. */
@ -1990,18 +1990,14 @@ linespec_parse_basic (linespec_parser *parser)
static void static void
canonicalize_linespec (struct linespec_state *state, const linespec *ls) canonicalize_linespec (struct linespec_state *state, const linespec *ls)
{ {
location_spec *canon;
struct explicit_location *explicit_loc;
/* If canonicalization was not requested, no need to do anything. */ /* If canonicalization was not requested, no need to do anything. */
if (!state->canonical) if (!state->canonical)
return; return;
/* Save everything as an explicit location. */ /* Save everything as an explicit location. */
state->canonical->locspec state->canonical->locspec = ls->explicit_loc.clone ();
= new_explicit_location_spec (&ls->explicit_loc); explicit_location_spec *explicit_loc
canon = state->canonical->locspec.get (); = as_explicit_location_spec (state->canonical->locspec.get ());
explicit_loc = get_explicit_location (canon);
if (explicit_loc->label_name != NULL) if (explicit_loc->label_name != NULL)
{ {
@ -2019,8 +2015,7 @@ canonicalize_linespec (struct linespec_state *state, const linespec *ls)
/* If this location originally came from a linespec, save a string /* If this location originally came from a linespec, save a string
representation of it for display and saving to file. */ representation of it for display and saving to file. */
if (state->is_linespec) if (state->is_linespec)
set_location_spec_string (canon, set_location_spec_string (explicit_loc, explicit_loc->to_linespec ());
explicit_location_to_linespec (explicit_loc));
} }
/* Given a line offset in LS, construct the relevant SALs. */ /* Given a line offset in LS, construct the relevant SALs. */
@ -2307,11 +2302,12 @@ convert_linespec_to_sals (struct linespec_state *state, linespec *ls)
return sals; return sals;
} }
/* Build RESULT from the explicit location components SOURCE_FILENAME, /* Build RESULT from the explicit location spec components
FUNCTION_NAME, LABEL_NAME and LINE_OFFSET. */ SOURCE_FILENAME, FUNCTION_NAME, LABEL_NAME and LINE_OFFSET. */
static void static void
convert_explicit_location_to_linespec (struct linespec_state *self, convert_explicit_location_spec_to_linespec
(struct linespec_state *self,
linespec *result, linespec *result,
const char *source_filename, const char *source_filename,
const char *function_name, const char *function_name,
@ -2382,16 +2378,17 @@ convert_explicit_location_to_linespec (struct linespec_state *self,
/* Convert the explicit location EXPLICIT_LOC into SaLs. */ /* Convert the explicit location EXPLICIT_LOC into SaLs. */
static std::vector<symtab_and_line> static std::vector<symtab_and_line>
convert_explicit_location_to_sals (struct linespec_state *self, convert_explicit_location_spec_to_sals
(struct linespec_state *self,
linespec *result, linespec *result,
const struct explicit_location *explicit_loc) const explicit_location_spec *explicit_spec)
{ {
convert_explicit_location_to_linespec (self, result, convert_explicit_location_spec_to_linespec (self, result,
explicit_loc->source_filename, explicit_spec->source_filename,
explicit_loc->function_name, explicit_spec->function_name,
explicit_loc->func_name_match_type, explicit_spec->func_name_match_type,
explicit_loc->label_name, explicit_spec->label_name,
explicit_loc->line_offset); explicit_spec->line_offset);
return convert_linespec_to_sals (self, result); return convert_linespec_to_sals (self, result);
} }
@ -2694,10 +2691,6 @@ linespec_state_destructor (struct linespec_state *self)
linespec_parser::~linespec_parser () linespec_parser::~linespec_parser ()
{ {
xfree (PARSER_EXPLICIT (this)->source_filename);
xfree (PARSER_EXPLICIT (this)->label_name);
xfree (PARSER_EXPLICIT (this)->function_name);
linespec_state_destructor (PARSER_STATE (this)); linespec_state_destructor (PARSER_STATE (this));
} }
@ -2855,7 +2848,7 @@ linespec_complete_label (completion_tracker &tracker,
try try
{ {
convert_explicit_location_to_linespec (PARSER_STATE (&parser), convert_explicit_location_spec_to_linespec (PARSER_STATE (&parser),
PARSER_RESULT (&parser), PARSER_RESULT (&parser),
source_filename, source_filename,
function_name, function_name,
@ -3073,24 +3066,18 @@ location_spec_to_sals (linespec_parser *parser,
{ {
case LINESPEC_LOCATION_SPEC: case LINESPEC_LOCATION_SPEC:
{ {
const linespec_location_spec *ls = as_linespec_location_spec (locspec);
PARSER_STATE (parser)->is_linespec = 1; PARSER_STATE (parser)->is_linespec = 1;
try result = parse_linespec (parser, ls->spec_string, ls->match_type);
{
const linespec_location *ls = get_linespec_location (locspec);
result = parse_linespec (parser,
ls->spec_string, ls->match_type);
}
catch (const gdb_exception_error &except)
{
throw;
}
} }
break; break;
case ADDRESS_LOCATION_SPEC: case ADDRESS_LOCATION_SPEC:
{ {
const char *addr_string = get_address_string_location (locspec); const address_location_spec *addr_spec
CORE_ADDR addr = get_address_location (locspec); = as_address_location_spec (locspec);
const char *addr_string = addr_spec->to_string ();
CORE_ADDR addr;
if (addr_string != NULL) if (addr_string != NULL)
{ {
@ -3099,6 +3086,8 @@ location_spec_to_sals (linespec_parser *parser,
PARSER_STATE (parser)->canonical->locspec PARSER_STATE (parser)->canonical->locspec
= copy_location_spec (locspec); = copy_location_spec (locspec);
} }
else
addr = addr_spec->address;
result = convert_address_location_to_sals (PARSER_STATE (parser), result = convert_address_location_to_sals (PARSER_STATE (parser),
addr); addr);
@ -3107,12 +3096,11 @@ location_spec_to_sals (linespec_parser *parser,
case EXPLICIT_LOCATION_SPEC: case EXPLICIT_LOCATION_SPEC:
{ {
const struct explicit_location *explicit_loc; const explicit_location_spec *explicit_locspec
= as_explicit_location_spec (locspec);
explicit_loc = get_explicit_location_const (locspec); result = convert_explicit_location_spec_to_sals (PARSER_STATE (parser),
result = convert_explicit_location_to_sals (PARSER_STATE (parser),
PARSER_RESULT (parser), PARSER_RESULT (parser),
explicit_loc); explicit_locspec);
} }
break; break;

View file

@ -29,104 +29,46 @@
#include <ctype.h> #include <ctype.h>
#include <string.h> #include <string.h>
static std::string explicit_location_to_string static std::string
(const struct explicit_location *explicit_loc); explicit_to_string_internal (bool as_linespec,
const explicit_location_spec *explicit_loc);
/* The base class for all location specs used to match actual /* Return a xstrdup of STR if not NULL, otherwise return NULL. */
locations in the inferior. */
struct location_spec static char *
maybe_xstrdup (const char *str)
{ {
virtual ~location_spec () = default; return (str != nullptr ? xstrdup (str) : nullptr);
/* Clone this object. */
virtual location_spec_up clone () const = 0;
/* Return true if this location spec is empty, false otherwise. */
virtual bool empty_p () const = 0;
/* Return a string representation of this location. */
const char *to_string () const
{
if (as_string.empty ())
as_string = compute_string ();
if (as_string.empty ())
return nullptr;
return as_string.c_str ();
} }
DISABLE_COPY_AND_ASSIGN (location_spec); probe_location_spec::probe_location_spec (std::string &&probe)
/* The type of this location specification. */
enum location_spec_type type;
/* Cached string representation of this location spec. This is
used, e.g., to save location specs to file. */
mutable std::string as_string;
protected:
explicit location_spec (enum location_spec_type t)
: type (t)
{
}
location_spec (enum location_spec_type t, std::string &&str)
: type (t),
as_string (std::move (str))
{
}
explicit location_spec (const location_spec *to_clone)
: type (to_clone->type),
as_string (to_clone->as_string)
{
}
/* Compute the string representation of this object. This is called
by to_string when needed. */
virtual std::string compute_string () const = 0;
};
/* A probe. */
struct probe_location_spec : public location_spec
{
explicit probe_location_spec (std::string &&probe)
: location_spec (PROBE_LOCATION_SPEC, std::move (probe)) : location_spec (PROBE_LOCATION_SPEC, std::move (probe))
{ {
} }
location_spec_up clone () const override location_spec_up
probe_location_spec::clone () const
{ {
return location_spec_up (new probe_location_spec (this)); return location_spec_up (new probe_location_spec (*this));
} }
bool empty_p () const override bool
probe_location_spec::empty_p () const
{ {
return false; return false;
} }
protected: std::string probe_location_spec::compute_string () const
explicit probe_location_spec (const probe_location_spec *to_clone)
: location_spec (to_clone)
{
}
std::string compute_string () const override
{ {
return std::move (as_string); return std::move (as_string);
} }
};
/* A "normal" linespec. */ /* A "normal" linespec. */
struct linespec_location_spec : public location_spec linespec_location_spec::linespec_location_spec
(const char **linespec, symbol_name_match_type match_type_)
: location_spec (LINESPEC_LOCATION_SPEC),
match_type (match_type_)
{ {
linespec_location_spec (const char **linespec,
symbol_name_match_type match_type)
: location_spec (LINESPEC_LOCATION_SPEC)
{
linespec_location.match_type = match_type;
if (*linespec != NULL) if (*linespec != NULL)
{ {
const char *p; const char *p;
@ -140,55 +82,50 @@ struct linespec_location_spec : public location_spec
breakpoint setting code, where spec_string being nullptr means breakpoint setting code, where spec_string being nullptr means
to use the default breakpoint location. */ to use the default breakpoint location. */
if ((p - orig) > 0) if ((p - orig) > 0)
linespec_location.spec_string = savestring (orig, p - orig); spec_string = savestring (orig, p - orig);
} }
} }
~linespec_location_spec () linespec_location_spec::~linespec_location_spec ()
{ {
xfree (linespec_location.spec_string); xfree (spec_string);
} }
location_spec_up clone () const override location_spec_up
linespec_location_spec::clone () const
{ {
return location_spec_up (new linespec_location_spec (this)); return location_spec_up (new linespec_location_spec (*this));
} }
bool empty_p () const override bool
linespec_location_spec::empty_p () const
{ {
return false; return false;
} }
struct linespec_location linespec_location {}; linespec_location_spec::linespec_location_spec
(const linespec_location_spec &other)
protected: : location_spec (other),
match_type (other.match_type),
explicit linespec_location_spec (const linespec_location_spec *to_clone) spec_string (maybe_xstrdup (other.spec_string))
: location_spec (to_clone),
linespec_location (to_clone->linespec_location)
{ {
if (linespec_location.spec_string != nullptr)
linespec_location.spec_string = xstrdup (linespec_location.spec_string);
} }
std::string compute_string () const override std::string
linespec_location_spec::compute_string () const
{ {
if (linespec_location.spec_string != nullptr) if (spec_string != nullptr)
{ {
const struct linespec_location *ls = &linespec_location; if (match_type == symbol_name_match_type::FULL)
if (ls->match_type == symbol_name_match_type::FULL) return std::string ("-qualified ") + spec_string;
return std::string ("-qualified ") + ls->spec_string;
else else
return ls->spec_string; return spec_string;
} }
return {}; return {};
} }
};
/* An address in the inferior. */ address_location_spec::address_location_spec (CORE_ADDR addr,
struct address_location_spec : public location_spec const char *addr_string,
{
address_location_spec (CORE_ADDR addr, const char *addr_string,
int addr_string_len) int addr_string_len)
: location_spec (ADDRESS_LOCATION_SPEC), : location_spec (ADDRESS_LOCATION_SPEC),
address (addr) address (addr)
@ -197,96 +134,76 @@ struct address_location_spec : public location_spec
as_string = std::string (addr_string, addr_string_len); as_string = std::string (addr_string, addr_string_len);
} }
location_spec_up clone () const override location_spec_up
address_location_spec::clone () const
{ {
return location_spec_up (new address_location_spec (this)); return location_spec_up (new address_location_spec (*this));
} }
bool empty_p () const override bool
address_location_spec::empty_p () const
{ {
return false; return false;
} }
CORE_ADDR address; address_location_spec::address_location_spec
(const address_location_spec &other)
protected: : location_spec (other),
address (other.address)
address_location_spec (const address_location_spec *to_clone)
: location_spec (to_clone),
address (to_clone->address)
{ {
} }
std::string compute_string () const override std::string
address_location_spec::compute_string () const
{ {
const char *addr_string = core_addr_to_string (address); const char *addr_string = core_addr_to_string (address);
return std::string ("*") + addr_string; return std::string ("*") + addr_string;
} }
};
/* An explicit location spec. */ explicit_location_spec::explicit_location_spec ()
struct explicit_location_spec : public location_spec
{
explicit explicit_location_spec (const struct explicit_location *loc)
: location_spec (EXPLICIT_LOCATION_SPEC) : location_spec (EXPLICIT_LOCATION_SPEC)
{ {
copy_loc (loc);
} }
~explicit_location_spec () explicit_location_spec::~explicit_location_spec ()
{ {
xfree (explicit_loc.source_filename); xfree (source_filename);
xfree (explicit_loc.function_name); xfree (function_name);
xfree (explicit_loc.label_name); xfree (label_name);
} }
location_spec_up clone () const override explicit_location_spec::explicit_location_spec
(const explicit_location_spec &other)
: location_spec (other),
source_filename (maybe_xstrdup (other.source_filename)),
function_name (maybe_xstrdup (other.function_name)),
func_name_match_type (other.func_name_match_type),
label_name (maybe_xstrdup (other.label_name)),
line_offset (other.line_offset)
{ {
return location_spec_up (new explicit_location_spec (this));
} }
bool empty_p () const override location_spec_up
explicit_location_spec::clone () const
{ {
return (explicit_loc.source_filename == nullptr return location_spec_up (new explicit_location_spec (*this));
&& explicit_loc.function_name == nullptr
&& explicit_loc.label_name == nullptr
&& explicit_loc.line_offset.sign == LINE_OFFSET_UNKNOWN);
} }
struct explicit_location explicit_loc; bool
explicit_location_spec::empty_p () const
protected:
explicit explicit_location_spec (const explicit_location_spec *to_clone)
: location_spec (to_clone)
{ {
copy_loc (&to_clone->explicit_loc); return (source_filename == nullptr
&& function_name == nullptr
&& label_name == nullptr
&& line_offset.sign == LINE_OFFSET_UNKNOWN);
} }
std::string compute_string () const override std::string
explicit_location_spec::compute_string () const
{ {
return explicit_location_to_string (&explicit_loc); return explicit_to_string_internal (false, this);
} }
private:
void copy_loc (const struct explicit_location *loc)
{
initialize_explicit_location (&explicit_loc);
if (loc != nullptr)
{
explicit_loc.func_name_match_type = loc->func_name_match_type;
if (loc->source_filename != nullptr)
explicit_loc.source_filename = xstrdup (loc->source_filename);
if (loc->function_name != nullptr)
explicit_loc.function_name = xstrdup (loc->function_name);
if (loc->label_name != nullptr)
explicit_loc.label_name = xstrdup (loc->label_name);
explicit_loc.line_offset = loc->line_offset;
}
}
};
/* See description in location.h. */ /* See description in location.h. */
enum location_spec_type enum location_spec_type
@ -297,16 +214,6 @@ location_spec_type (const location_spec *locspec)
/* See description in location.h. */ /* See description in location.h. */
void
initialize_explicit_location (struct explicit_location *explicit_loc)
{
memset (explicit_loc, 0, sizeof (struct explicit_location));
explicit_loc->line_offset.sign = LINE_OFFSET_UNKNOWN;
explicit_loc->func_name_match_type = symbol_name_match_type::WILD;
}
/* See description in location.h. */
location_spec_up location_spec_up
new_linespec_location_spec (const char **linespec, new_linespec_location_spec (const char **linespec,
symbol_name_match_type match_type) symbol_name_match_type match_type)
@ -317,11 +224,11 @@ new_linespec_location_spec (const char **linespec,
/* See description in location.h. */ /* See description in location.h. */
const linespec_location * const linespec_location_spec *
get_linespec_location (const location_spec *locspec) as_linespec_location_spec (const location_spec *locspec)
{ {
gdb_assert (locspec->type == LINESPEC_LOCATION_SPEC); gdb_assert (locspec->type == LINESPEC_LOCATION_SPEC);
return &((linespec_location_spec *) locspec)->linespec_location; return static_cast<const linespec_location_spec *> (locspec);
} }
/* See description in location.h. */ /* See description in location.h. */
@ -336,20 +243,11 @@ new_address_location_spec (CORE_ADDR addr, const char *addr_string,
/* See description in location.h. */ /* See description in location.h. */
CORE_ADDR const address_location_spec *
get_address_location (const location_spec *locspec) as_address_location_spec (const location_spec *locspec)
{ {
gdb_assert (locspec->type == ADDRESS_LOCATION_SPEC); gdb_assert (locspec->type == ADDRESS_LOCATION_SPEC);
return ((address_location_spec *) locspec)->address; return static_cast<const address_location_spec *> (locspec);
}
/* See description in location.h. */
const char *
get_address_string_location (const location_spec *locspec)
{
gdb_assert (locspec->type == ADDRESS_LOCATION_SPEC);
return locspec->to_string ();
} }
/* See description in location.h. */ /* See description in location.h. */
@ -362,37 +260,29 @@ new_probe_location_spec (std::string &&probe)
/* See description in location.h. */ /* See description in location.h. */
const char * const probe_location_spec *
get_probe_location_spec_string (const location_spec *locspec) as_probe_location_spec (const location_spec *locspec)
{ {
gdb_assert (locspec->type == PROBE_LOCATION_SPEC); gdb_assert (locspec->type == PROBE_LOCATION_SPEC);
return locspec->to_string (); return static_cast<const probe_location_spec *> (locspec);
} }
/* See description in location.h. */ /* See description in location.h. */
location_spec_up const explicit_location_spec *
new_explicit_location_spec (const explicit_location *explicit_loc) as_explicit_location_spec (const location_spec *locspec)
{
return location_spec_up (new explicit_location_spec (explicit_loc));
}
/* See description in location.h. */
struct explicit_location *
get_explicit_location (location_spec *locspec)
{ {
gdb_assert (locspec->type == EXPLICIT_LOCATION_SPEC); gdb_assert (locspec->type == EXPLICIT_LOCATION_SPEC);
return &((explicit_location_spec *) locspec)->explicit_loc; return static_cast<const explicit_location_spec *> (locspec);
} }
/* See description in location.h. */ /* See description in location.h. */
const struct explicit_location * explicit_location_spec *
get_explicit_location_const (const location_spec *locspec) as_explicit_location_spec (location_spec *locspec)
{ {
gdb_assert (locspec->type == EXPLICIT_LOCATION_SPEC); gdb_assert (locspec->type == EXPLICIT_LOCATION_SPEC);
return &((explicit_location_spec *) locspec)->explicit_loc; return static_cast<explicit_location_spec *> (locspec);
} }
/* Return a string representation of the explicit location spec in /* Return a string representation of the explicit location spec in
@ -403,7 +293,7 @@ get_explicit_location_const (const location_spec *locspec)
static std::string static std::string
explicit_to_string_internal (bool as_linespec, explicit_to_string_internal (bool as_linespec,
const struct explicit_location *explicit_loc) const explicit_location_spec *explicit_loc)
{ {
bool need_space = false; bool need_space = false;
char space = as_linespec ? ':' : ' '; char space = as_linespec ? ':' : ' ';
@ -457,18 +347,10 @@ explicit_to_string_internal (bool as_linespec,
/* See description in location.h. */ /* See description in location.h. */
static std::string
explicit_location_to_string (const struct explicit_location *explicit_loc)
{
return explicit_to_string_internal (false, explicit_loc);
}
/* See description in location.h. */
std::string std::string
explicit_location_to_linespec (const struct explicit_location *explicit_loc) explicit_location_spec::to_linespec () const
{ {
return explicit_to_string_internal (true, explicit_loc); return explicit_to_string_internal (true, this);
} }
/* See description in location.h. */ /* See description in location.h. */
@ -479,12 +361,6 @@ copy_location_spec (const location_spec *src)
return src->clone (); return src->clone ();
} }
void
location_spec_deleter::operator() (location_spec *locspec) const
{
delete locspec;
}
/* See description in location.h. */ /* See description in location.h. */
const char * const char *
@ -788,7 +664,7 @@ string_to_explicit_location_spec (const char **argp,
return NULL; return NULL;
std::unique_ptr<explicit_location_spec> locspec std::unique_ptr<explicit_location_spec> locspec
(new explicit_location_spec ((const explicit_location *) nullptr)); (new explicit_location_spec ());
/* Process option/argument pairs. dprintf_command /* Process option/argument pairs. dprintf_command
requires that processing stop on ','. */ requires that processing stop on ','. */
@ -857,18 +733,17 @@ string_to_explicit_location_spec (const char **argp,
{ {
set_oarg (explicit_location_spec_lex_one (argp, language, set_oarg (explicit_location_spec_lex_one (argp, language,
completion_info)); completion_info));
locspec->explicit_loc.source_filename = oarg.release (); locspec->source_filename = oarg.release ();
} }
else if (strncmp (opt.get (), "-function", len) == 0) else if (strncmp (opt.get (), "-function", len) == 0)
{ {
set_oarg (explicit_location_spec_lex_one_function (argp, language, set_oarg (explicit_location_spec_lex_one_function (argp, language,
completion_info)); completion_info));
locspec->explicit_loc.function_name = oarg.release (); locspec->function_name = oarg.release ();
} }
else if (strncmp (opt.get (), "-qualified", len) == 0) else if (strncmp (opt.get (), "-qualified", len) == 0)
{ {
locspec->explicit_loc.func_name_match_type locspec->func_name_match_type = symbol_name_match_type::FULL;
= symbol_name_match_type::FULL;
} }
else if (strncmp (opt.get (), "-line", len) == 0) else if (strncmp (opt.get (), "-line", len) == 0)
{ {
@ -876,8 +751,7 @@ string_to_explicit_location_spec (const char **argp,
*argp = skip_spaces (*argp); *argp = skip_spaces (*argp);
if (have_oarg) if (have_oarg)
{ {
locspec->explicit_loc.line_offset locspec->line_offset = linespec_parse_line_offset (oarg.get ());
= linespec_parse_line_offset (oarg.get ());
continue; continue;
} }
} }
@ -885,7 +759,7 @@ string_to_explicit_location_spec (const char **argp,
{ {
set_oarg (explicit_location_spec_lex_one (argp, language, set_oarg (explicit_location_spec_lex_one (argp, language,
completion_info)); completion_info));
locspec->explicit_loc.label_name = oarg.release (); locspec->label_name = oarg.release ();
} }
/* Only emit an "invalid argument" error for options /* Only emit an "invalid argument" error for options
that look like option strings. */ that look like option strings. */
@ -915,10 +789,10 @@ string_to_explicit_location_spec (const char **argp,
/* One special error check: If a source filename was given /* One special error check: If a source filename was given
without offset, function, or label, issue an error. */ without offset, function, or label, issue an error. */
if (locspec->explicit_loc.source_filename != NULL if (locspec->source_filename != NULL
&& locspec->explicit_loc.function_name == NULL && locspec->function_name == NULL
&& locspec->explicit_loc.label_name == NULL && locspec->label_name == NULL
&& (locspec->explicit_loc.line_offset.sign == LINE_OFFSET_UNKNOWN) && (locspec->line_offset.sign == LINE_OFFSET_UNKNOWN)
&& completion_info == NULL) && completion_info == NULL)
{ {
error (_("Source filename requires function, label, or " error (_("Source filename requires function, label, or "
@ -1000,7 +874,7 @@ string_to_location_spec (const char **stringp,
explicit_location_spec *xloc explicit_location_spec *xloc
= dynamic_cast<explicit_location_spec *> (locspec.get ()); = dynamic_cast<explicit_location_spec *> (locspec.get ());
gdb_assert (xloc != nullptr); gdb_assert (xloc != nullptr);
match_type = xloc->explicit_loc.func_name_match_type; match_type = xloc->func_name_match_type;
} }
/* Everything else is a "basic" linespec, address, or probe location /* Everything else is a "basic" linespec, address, or probe location

View file

@ -46,8 +46,8 @@ enum offset_relative_sign
struct line_offset struct line_offset
{ {
/* Line offset and any specified sign. */ /* Line offset and any specified sign. */
int offset; int offset = 0;
enum offset_relative_sign sign; enum offset_relative_sign sign = LINE_OFFSET_UNKNOWN;
}; };
/* An enumeration of the various ways to specify a location spec. */ /* An enumeration of the various ways to specify a location spec. */
@ -67,15 +67,104 @@ enum location_spec_type
PROBE_LOCATION_SPEC PROBE_LOCATION_SPEC
}; };
/* A traditional linespec. */ /* A unique pointer for location_spec. */
typedef std::unique_ptr<location_spec> location_spec_up;
struct linespec_location /* The base class for all location specs used to resolve actual
locations in the inferior. */
struct location_spec
{ {
virtual ~location_spec () = default;
/* Clone this object. */
virtual location_spec_up clone () const = 0;
/* Return true if this location spec is empty, false otherwise. */
virtual bool empty_p () const = 0;
/* Return a string representation of this location. */
const char *to_string () const
{
if (as_string.empty ())
as_string = compute_string ();
if (as_string.empty ())
return nullptr;
return as_string.c_str ();
}
/* The type of this location specification. */
enum location_spec_type type;
/* Cached string representation of this location spec. This is
used, e.g., to save location specs to file. */
mutable std::string as_string;
protected:
explicit location_spec (enum location_spec_type t)
: type (t)
{
}
location_spec (enum location_spec_type t, std::string &&str)
: type (t),
as_string (std::move (str))
{
}
location_spec (const location_spec &other)
: type (other.type),
as_string (other.as_string)
{
}
/* Compute the string representation of this object. This is called
by to_string when needed. */
virtual std::string compute_string () const = 0;
};
/* A "normal" linespec. */
struct linespec_location_spec : public location_spec
{
linespec_location_spec (const char **linespec,
symbol_name_match_type match_type);
~linespec_location_spec ();
location_spec_up clone () const override;
bool empty_p () const override;
/* Whether the function name is fully-qualified or not. */ /* Whether the function name is fully-qualified or not. */
symbol_name_match_type match_type; symbol_name_match_type match_type;
/* The linespec. */ /* The linespec. */
char *spec_string; char *spec_string = nullptr;
protected:
linespec_location_spec (const linespec_location_spec &other);
std::string compute_string () const override;
};
/* An address in the inferior. */
struct address_location_spec : public location_spec
{
address_location_spec (CORE_ADDR addr, const char *addr_string,
int addr_string_len);
location_spec_up clone () const override;
bool empty_p () const override;
CORE_ADDR address;
protected:
address_location_spec (const address_location_spec &other);
std::string compute_string () const override;
}; };
/* An explicit location spec. This structure is used to bypass the /* An explicit location spec. This structure is used to bypass the
@ -83,24 +172,58 @@ struct linespec_location
as linespecs, though. For example, source_filename requires as linespecs, though. For example, source_filename requires
at least one other field. */ at least one other field. */
struct explicit_location struct explicit_location_spec : public location_spec
{ {
explicit_location_spec ();
~explicit_location_spec ();
location_spec_up clone () const override;
bool empty_p () const override;
/* Return a linespec string representation of this explicit location
spec. The explicit location spec must already be
canonicalized/valid. */
std::string to_linespec () const;
/* The source filename. Malloc'd. */ /* The source filename. Malloc'd. */
char *source_filename; char *source_filename = nullptr;
/* The function name. Malloc'd. */ /* The function name. Malloc'd. */
char *function_name; char *function_name = nullptr;
/* Whether the function name is fully-qualified or not. */ /* Whether the function name is fully-qualified or not. */
symbol_name_match_type func_name_match_type; symbol_name_match_type func_name_match_type
= symbol_name_match_type::WILD;
/* The name of a label. Malloc'd. */ /* The name of a label. Malloc'd. */
char *label_name; char *label_name = nullptr;
/* A line offset relative to the start of the symbol /* A line offset relative to the start of the symbol
identified by the above fields or the current symtab identified by the above fields or the current symtab
if the other fields are NULL. */ if the other fields are NULL. */
struct line_offset line_offset; struct line_offset line_offset = {0, LINE_OFFSET_UNKNOWN};
protected:
explicit_location_spec (const explicit_location_spec &other);
std::string compute_string () const override;
};
/* A probe. */
struct probe_location_spec : public location_spec
{
explicit probe_location_spec (std::string &&probe);
location_spec_up clone () const override;
bool empty_p () const override;
protected:
probe_location_spec (const probe_location_spec &other) = default;
std::string compute_string () const override;
}; };
/* Return the type of the given location spec. */ /* Return the type of the given location spec. */
@ -108,13 +231,6 @@ struct explicit_location
extern enum location_spec_type extern enum location_spec_type
location_spec_type (const location_spec *); location_spec_type (const location_spec *);
/* Return a linespec string representation of the given explicit
location spec. The location spec must already be
canonicalized/valid. */
extern std::string explicit_location_to_linespec
(const explicit_location *explicit_locspec);
/* Return a string representation of LOCSPEC. /* Return a string representation of LOCSPEC.
This function may return NULL for unspecified linespecs, This function may return NULL for unspecified linespecs,
e.g, LINESPEC_LOCATION_SPEC and spec_string is NULL. e.g, LINESPEC_LOCATION_SPEC and spec_string is NULL.
@ -124,27 +240,16 @@ extern std::string explicit_location_to_linespec
extern const char * extern const char *
location_spec_to_string (location_spec *locspec); location_spec_to_string (location_spec *locspec);
/* A deleter for a struct location_spec. */
struct location_spec_deleter
{
void operator() (location_spec *locspec) const;
};
/* A unique pointer for location_spec. */
typedef std::unique_ptr<location_spec, location_spec_deleter>
location_spec_up;
/* Create a new linespec location spec. */ /* Create a new linespec location spec. */
extern location_spec_up new_linespec_location_spec extern location_spec_up new_linespec_location_spec
(const char **linespec, symbol_name_match_type match_type); (const char **linespec, symbol_name_match_type match_type);
/* Return the linespec location spec of the given location_spec (which /* Return the given location_spec as a linespec_location_spec.
must be of type LINESPEC_LOCATION_SPEC). */ LOCSPEC must be of type LINESPEC_LOCATION_SPEC. */
extern const linespec_location * extern const linespec_location_spec *
get_linespec_location (const location_spec *locspec); as_linespec_location_spec (const location_spec *locspec);
/* Create a new address location spec. /* Create a new address location spec.
ADDR is the address corresponding to this location_spec. ADDR is the address corresponding to this location_spec.
@ -155,50 +260,42 @@ extern location_spec_up new_address_location_spec (CORE_ADDR addr,
const char *addr_string, const char *addr_string,
int addr_string_len); int addr_string_len);
/* Return the address (a CORE_ADDR) of the given location_spec, which /* Return the given location_spec as an address_location_spec.
must be of type ADDRESS_LOCATION_SPEC. */ LOCSPEC must be of type ADDRESS_LOCATION_SPEC. */
extern CORE_ADDR const address_location_spec *
get_address_location (const location_spec *locspec); as_address_location_spec (const location_spec *locspec);
/* Return the expression (a string) that was used to compute the
address of the given location_spec, which must be of type
ADDRESS_LOCATION_SPEC. */
extern const char *
get_address_string_location (const location_spec *locspec);
/* Create a new probe location. */ /* Create a new probe location. */
extern location_spec_up new_probe_location_spec (std::string &&probe); extern location_spec_up new_probe_location_spec (std::string &&probe);
/* Return the probe location spec string of the given location_spec, /* Assuming LOCSPEC is of type PROBE_LOCATION_SPEC, return LOCSPEC
which must be of type PROBE_LOCATION_SPEC. */ cast to probe_location_spec. */
extern const char * const probe_location_spec *
get_probe_location_spec_string (const location_spec *locspec); as_probe_location_spec (const location_spec *locspec);
/* Initialize the given explicit location. */ /* Create a new explicit location with explicit FUNCTION_NAME. All
other fields are defaulted. */
extern void static inline location_spec_up
initialize_explicit_location (explicit_location *locspec); new_explicit_location_spec_function (const char *function_name)
{
explicit_location_spec *spec
= new explicit_location_spec ();
spec->function_name
= (function_name != nullptr ? xstrdup (function_name) : nullptr);
return location_spec_up (spec);
}
/* Create a new explicit location. If not NULL, EXPLICIT is checked for /* Assuming LOCSPEC is of type EXPLICIT_LOCATION_SPEC, return LOCSPEC
validity. If invalid, an exception is thrown. */ cast to explicit_location_spec. */
extern location_spec_up const explicit_location_spec *
new_explicit_location_spec (const explicit_location *locspec); as_explicit_location_spec (const location_spec *locspec);
explicit_location_spec *
/* Return the explicit location spec of the given location_spec, which as_explicit_location_spec (location_spec *locspec);
must be of type EXPLICIT_LOCATION. */
extern struct explicit_location *
get_explicit_location (location_spec *locspec);
/* A const version of the above. */
extern const explicit_location *
get_explicit_location_const (const location_spec *locspec);
/* Return a copy of the given SRC location spec. */ /* Return a copy of the given SRC location spec. */

View file

@ -182,7 +182,8 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
location_spec_up locspec; location_spec_up locspec;
const struct breakpoint_ops *ops; const struct breakpoint_ops *ops;
int is_explicit = 0; int is_explicit = 0;
struct explicit_location explicit_loc; std::unique_ptr<explicit_location_spec> explicit_loc
(new explicit_location_spec ());
std::string extra_string; std::string extra_string;
bool force_condition = false; bool force_condition = false;
@ -220,8 +221,6 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
int oind = 0; int oind = 0;
char *oarg; char *oarg;
initialize_explicit_location (&explicit_loc);
while (1) while (1)
{ {
int opt = mi_getopt ("-break-insert", argc, argv, int opt = mi_getopt ("-break-insert", argc, argv,
@ -259,19 +258,19 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
break; break;
case EXPLICIT_SOURCE_OPT: case EXPLICIT_SOURCE_OPT:
is_explicit = 1; is_explicit = 1;
explicit_loc.source_filename = oarg; explicit_loc->source_filename = xstrdup (oarg);
break; break;
case EXPLICIT_FUNC_OPT: case EXPLICIT_FUNC_OPT:
is_explicit = 1; is_explicit = 1;
explicit_loc.function_name = oarg; explicit_loc->function_name = xstrdup (oarg);
break; break;
case EXPLICIT_LABEL_OPT: case EXPLICIT_LABEL_OPT:
is_explicit = 1; is_explicit = 1;
explicit_loc.label_name = oarg; explicit_loc->label_name = xstrdup (oarg);
break; break;
case EXPLICIT_LINE_OPT: case EXPLICIT_LINE_OPT:
is_explicit = 1; is_explicit = 1;
explicit_loc.line_offset = linespec_parse_line_offset (oarg); explicit_loc->line_offset = linespec_parse_line_offset (oarg);
break; break;
case FORCE_CONDITION_OPT: case FORCE_CONDITION_OPT:
force_condition = true; force_condition = true;
@ -339,16 +338,16 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
{ {
/* Error check -- we must have one of the other /* Error check -- we must have one of the other
parameters specified. */ parameters specified. */
if (explicit_loc.source_filename != NULL if (explicit_loc->source_filename != NULL
&& explicit_loc.function_name == NULL && explicit_loc->function_name == NULL
&& explicit_loc.label_name == NULL && explicit_loc->label_name == NULL
&& explicit_loc.line_offset.sign == LINE_OFFSET_UNKNOWN) && explicit_loc->line_offset.sign == LINE_OFFSET_UNKNOWN)
error (_("-%s-insert: --source option requires --function, --label," error (_("-%s-insert: --source option requires --function, --label,"
" or --line"), dprintf ? "dprintf" : "break"); " or --line"), dprintf ? "dprintf" : "break");
explicit_loc.func_name_match_type = match_type; explicit_loc->func_name_match_type = match_type;
locspec = new_explicit_location_spec (&explicit_loc); locspec = std::move (explicit_loc);
} }
else else
{ {

View file

@ -123,7 +123,7 @@ parse_probes (const location_spec *locspec,
const char *arg_start, *cs; const char *arg_start, *cs;
gdb_assert (location_spec_type (locspec) == PROBE_LOCATION_SPEC); gdb_assert (location_spec_type (locspec) == PROBE_LOCATION_SPEC);
arg_start = get_probe_location_spec_string (locspec); arg_start = locspec->to_string ();
cs = arg_start; cs = arg_start;
const static_probe_ops *spops = probe_linespec_to_static_ops (&cs); const static_probe_ops *spops = probe_linespec_to_static_ops (&cs);

View file

@ -839,20 +839,23 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
} }
else else
{ {
struct explicit_location explicit_loc; std::unique_ptr<explicit_location_spec> explicit_loc
(new explicit_location_spec ());
initialize_explicit_location (&explicit_loc); explicit_loc->source_filename
explicit_loc.source_filename = source; = source != nullptr ? xstrdup (source) : nullptr;
explicit_loc.function_name = function; explicit_loc->function_name
explicit_loc.label_name = label; = function != nullptr ? xstrdup (function) : nullptr;
explicit_loc->label_name
= label != nullptr ? xstrdup (label) : nullptr;
if (line != NULL) if (line != NULL)
explicit_loc.line_offset = explicit_loc->line_offset
linespec_parse_line_offset (line.get ()); = linespec_parse_line_offset (line.get ());
explicit_loc.func_name_match_type = func_name_match_type; explicit_loc->func_name_match_type = func_name_match_type;
locspec = new_explicit_location_spec (&explicit_loc); locspec.reset (explicit_loc.release ());
} }
const struct breakpoint_ops *ops const struct breakpoint_ops *ops