From: Pedro Alves Date: Fri, 27 May 2022 12:13:41 +0000 (+0100) Subject: Eliminate the two-level data structures behind location_specs X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=40d97ee21fc3e39db73ee8f84b847a22f9d251cc;p=binutils-gdb.git 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 --- diff --git a/gdb/break-catch-throw.c b/gdb/break-catch-throw.c index 3ef4b972d4f..2eb24f3b76c 100644 --- a/gdb/break-catch-throw.c +++ b/gdb/break-catch-throw.c @@ -225,12 +225,9 @@ exception_catchpoint::re_set () catchpoint mode. */ try { - struct explicit_location explicit_loc; - - initialize_explicit_location (&explicit_loc); - explicit_loc.function_name - = ASTRDUP (exception_functions[kind].function); - location_spec_up locspec = new_explicit_location_spec (&explicit_loc); + location_spec_up locspec + = (new_explicit_location_spec_function + (exception_functions[kind].function)); sals = this->decode_location_spec (locspec.get (), filter_pspace); } catch (const gdb_exception_error &ex) diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c index ab88a38e0a3..82937a3b78a 100644 --- a/gdb/breakpoint.c +++ b/gdb/breakpoint.c @@ -3364,7 +3364,6 @@ create_overlay_event_breakpoint (void) struct breakpoint *b; struct breakpoint_objfile_data *bp_objfile_data; CORE_ADDR addr; - struct explicit_location explicit_loc; 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 (); b = create_internal_breakpoint (objfile->arch (), addr, bp_overlay_event); - initialize_explicit_location (&explicit_loc); - explicit_loc.function_name = ASTRDUP (func_name); - b->locspec = new_explicit_location_spec (&explicit_loc); + b->locspec = new_explicit_location_spec_function (func_name); if (overlay_debugging == ovly_auto) { @@ -3473,7 +3470,6 @@ create_longjmp_master_breakpoint_names (objfile *objfile) struct breakpoint *b; const char *func_name; CORE_ADDR addr; - struct explicit_location explicit_loc; if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym)) continue; @@ -3495,9 +3491,7 @@ create_longjmp_master_breakpoint_names (objfile *objfile) addr = bp_objfile_data->longjmp_msym[i].value_address (); b = create_internal_breakpoint (gdbarch, addr, bp_longjmp_master); - initialize_explicit_location (&explicit_loc); - explicit_loc.function_name = ASTRDUP (func_name); - b->locspec = new_explicit_location_spec (&explicit_loc); + b->locspec = new_explicit_location_spec_function (func_name); b->enable_state = bp_disabled; installed_bp++; } @@ -3553,7 +3547,6 @@ create_std_terminate_master_breakpoint (void) { struct breakpoint *b; struct breakpoint_objfile_data *bp_objfile_data; - struct explicit_location explicit_loc; 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 (); b = create_internal_breakpoint (objfile->arch (), addr, bp_std_terminate_master); - initialize_explicit_location (&explicit_loc); - explicit_loc.function_name = ASTRDUP (func_name); - b->locspec = new_explicit_location_spec (&explicit_loc); + b->locspec = new_explicit_location_spec_function (func_name); b->enable_state = bp_disabled; } } @@ -3648,7 +3639,6 @@ create_exception_master_breakpoint_hook (objfile *objfile) struct gdbarch *gdbarch; struct breakpoint_objfile_data *bp_objfile_data; CORE_ADDR addr; - struct explicit_location explicit_loc; 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 (gdbarch, addr, current_inferior ()->top_target ()); b = create_internal_breakpoint (gdbarch, addr, bp_exception_master); - initialize_explicit_location (&explicit_loc); - explicit_loc.function_name = ASTRDUP (func_name); - b->locspec = new_explicit_location_spec (&explicit_loc); + b->locspec = new_explicit_location_spec_function (func_name); b->enable_state = bp_disabled; return true; @@ -8467,7 +8455,7 @@ parse_breakpoint_sals (location_spec *locspec, 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) { @@ -8518,7 +8506,7 @@ parse_breakpoint_sals (location_spec *locspec, const char *spec = NULL; 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 || (spec != NULL @@ -12005,7 +11993,7 @@ strace_marker_create_sals_from_location_spec (location_spec *locspec, struct linespec_sals lsal; 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); std::string str (arg_start, arg - arg_start); @@ -12073,7 +12061,7 @@ std::vector static_marker_tracepoint::decode_location_spec (location_spec *locspec, 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 sals = decode_static_tracepoint_spec (&s); 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 static_tracepoint_marker *tpmarker; struct ui_out *uiout = current_uiout; - struct explicit_location explicit_loc; 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->symtab = sym != NULL ? sal2.symtab : NULL; - b->locspec.reset (nullptr); - initialize_explicit_location (&explicit_loc); - explicit_loc.source_filename - = ASTRDUP (symtab_to_filename_for_display (sal2.symtab)); - explicit_loc.line_offset.offset = b->loc->line_number; - explicit_loc.line_offset.sign = LINE_OFFSET_NONE; - b->locspec = new_explicit_location_spec (&explicit_loc); + std::unique_ptr els + (new explicit_location_spec ()); + els->source_filename + = xstrdup (symtab_to_filename_for_display (sal2.symtab)); + els->line_offset.offset = b->loc->line_number; + els->line_offset.sign = LINE_OFFSET_NONE; + + b->locspec = std::move (els); /* Might be nice to check if function changed, and warn if so. */ diff --git a/gdb/completer.c b/gdb/completer.c index 2ec8d2eb594..b68b6de2057 100644 --- a/gdb/completer.c +++ b/gdb/completer.c @@ -712,8 +712,8 @@ collect_explicit_location_matches (completion_tracker &tracker, const char *word, const struct language_defn *language) { - const struct explicit_location *explicit_loc - = get_explicit_location (locspec); + const explicit_location_spec *explicit_loc + = as_explicit_location_spec (locspec); /* True if the option expects an argument. */ bool needs_arg = true; @@ -1008,7 +1008,7 @@ location_completer (struct cmd_list_element *ignore, text = copy; 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); } } diff --git a/gdb/linespec.c b/gdb/linespec.c index b12f5c87733..063944bb9a1 100644 --- a/gdb/linespec.c +++ b/gdb/linespec.c @@ -94,8 +94,8 @@ struct address_entry struct linespec { - /* An explicit location describing the SaLs. */ - struct explicit_location explicit_loc {}; + /* An explicit location spec describing the SaLs. */ + explicit_location_spec explicit_loc; /* 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; }; -/* A convenience macro for accessing the explicit location result of - the parser. */ +/* A convenience macro for accessing the explicit location spec result + of the parser. */ #define PARSER_EXPLICIT(PPTR) (&PARSER_RESULT ((PPTR))->explicit_loc) /* Prototypes for local functions. */ @@ -1990,18 +1990,14 @@ linespec_parse_basic (linespec_parser *parser) static void 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 (!state->canonical) return; /* Save everything as an explicit location. */ - state->canonical->locspec - = new_explicit_location_spec (&ls->explicit_loc); - canon = state->canonical->locspec.get (); - explicit_loc = get_explicit_location (canon); + state->canonical->locspec = ls->explicit_loc.clone (); + explicit_location_spec *explicit_loc + = as_explicit_location_spec (state->canonical->locspec.get ()); 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 representation of it for display and saving to file. */ if (state->is_linespec) - set_location_spec_string (canon, - explicit_location_to_linespec (explicit_loc)); + set_location_spec_string (explicit_loc, explicit_loc->to_linespec ()); } /* Given a line offset in LS, construct the relevant SALs. */ @@ -2307,17 +2302,18 @@ convert_linespec_to_sals (struct linespec_state *state, linespec *ls) return sals; } -/* Build RESULT from the explicit location components SOURCE_FILENAME, - FUNCTION_NAME, LABEL_NAME and LINE_OFFSET. */ +/* Build RESULT from the explicit location spec components + SOURCE_FILENAME, FUNCTION_NAME, LABEL_NAME and LINE_OFFSET. */ static void -convert_explicit_location_to_linespec (struct linespec_state *self, - 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) +convert_explicit_location_spec_to_linespec + (struct linespec_state *self, + 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 minimal_symbols; @@ -2382,16 +2378,17 @@ convert_explicit_location_to_linespec (struct linespec_state *self, /* Convert the explicit location EXPLICIT_LOC into SaLs. */ static std::vector -convert_explicit_location_to_sals (struct linespec_state *self, - linespec *result, - const struct explicit_location *explicit_loc) +convert_explicit_location_spec_to_sals + (struct linespec_state *self, + linespec *result, + const explicit_location_spec *explicit_spec) { - convert_explicit_location_to_linespec (self, result, - explicit_loc->source_filename, - explicit_loc->function_name, - explicit_loc->func_name_match_type, - explicit_loc->label_name, - explicit_loc->line_offset); + convert_explicit_location_spec_to_linespec (self, result, + explicit_spec->source_filename, + explicit_spec->function_name, + explicit_spec->func_name_match_type, + explicit_spec->label_name, + explicit_spec->line_offset); return convert_linespec_to_sals (self, result); } @@ -2694,10 +2691,6 @@ linespec_state_destructor (struct linespec_state *self) 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)); } @@ -2855,12 +2848,12 @@ linespec_complete_label (completion_tracker &tracker, try { - convert_explicit_location_to_linespec (PARSER_STATE (&parser), - PARSER_RESULT (&parser), - source_filename, - function_name, - func_name_match_type, - NULL, unknown_offset); + convert_explicit_location_spec_to_linespec (PARSER_STATE (&parser), + PARSER_RESULT (&parser), + source_filename, + function_name, + func_name_match_type, + NULL, unknown_offset); } catch (const gdb_exception_error &ex) { @@ -3073,24 +3066,18 @@ location_spec_to_sals (linespec_parser *parser, { case LINESPEC_LOCATION_SPEC: { + const linespec_location_spec *ls = as_linespec_location_spec (locspec); PARSER_STATE (parser)->is_linespec = 1; - try - { - 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; - } + result = parse_linespec (parser, ls->spec_string, ls->match_type); } break; case ADDRESS_LOCATION_SPEC: { - const char *addr_string = get_address_string_location (locspec); - CORE_ADDR addr = get_address_location (locspec); + const address_location_spec *addr_spec + = as_address_location_spec (locspec); + const char *addr_string = addr_spec->to_string (); + CORE_ADDR addr; if (addr_string != NULL) { @@ -3099,6 +3086,8 @@ location_spec_to_sals (linespec_parser *parser, PARSER_STATE (parser)->canonical->locspec = copy_location_spec (locspec); } + else + addr = addr_spec->address; result = convert_address_location_to_sals (PARSER_STATE (parser), addr); @@ -3107,12 +3096,11 @@ location_spec_to_sals (linespec_parser *parser, case EXPLICIT_LOCATION_SPEC: { - const struct explicit_location *explicit_loc; - - explicit_loc = get_explicit_location_const (locspec); - result = convert_explicit_location_to_sals (PARSER_STATE (parser), - PARSER_RESULT (parser), - explicit_loc); + const explicit_location_spec *explicit_locspec + = as_explicit_location_spec (locspec); + result = convert_explicit_location_spec_to_sals (PARSER_STATE (parser), + PARSER_RESULT (parser), + explicit_locspec); } break; diff --git a/gdb/location.c b/gdb/location.c index 14a5aebff17..4d0b60ff9c7 100644 --- a/gdb/location.c +++ b/gdb/location.c @@ -29,280 +29,187 @@ #include #include -static std::string explicit_location_to_string - (const struct explicit_location *explicit_loc); +static std::string + explicit_to_string_internal (bool as_linespec, + const explicit_location_spec *explicit_loc); + +/* Return a xstrdup of STR if not NULL, otherwise return NULL. */ -/* The base class for all location specs used to match actual - locations in the inferior. */ +static char * +maybe_xstrdup (const char *str) +{ + return (str != nullptr ? xstrdup (str) : nullptr); +} + +probe_location_spec::probe_location_spec (std::string &&probe) + : location_spec (PROBE_LOCATION_SPEC, std::move (probe)) +{ +} -struct location_spec +location_spec_up +probe_location_spec::clone () const { - 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 (); - } - - DISABLE_COPY_AND_ASSIGN (location_spec); - - /* 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 + return location_spec_up (new probe_location_spec (*this)); +} + +bool +probe_location_spec::empty_p () const { - explicit probe_location_spec (std::string &&probe) - : location_spec (PROBE_LOCATION_SPEC, std::move (probe)) - { - } - - location_spec_up clone () const override - { - return location_spec_up (new probe_location_spec (this)); - } - - bool empty_p () const override - { - return false; - } - -protected: - - 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 false; +} + +std::string probe_location_spec::compute_string () const +{ + return std::move (as_string); +} /* 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) - { - const char *p; - const char *orig = *linespec; - - linespec_lex_to_end (linespec); - p = remove_trailing_whitespace (orig, *linespec); - - /* If there is no valid linespec then this will leave the - spec_string as nullptr. This behaviour is relied on in the - breakpoint setting code, where spec_string being nullptr means - to use the default breakpoint location. */ - if ((p - orig) > 0) - linespec_location.spec_string = savestring (orig, p - orig); - } - } - - ~linespec_location_spec () - { - xfree (linespec_location.spec_string); - } - - location_spec_up clone () const override - { - return location_spec_up (new linespec_location_spec (this)); - } - - bool empty_p () const override - { - return false; - } - - struct linespec_location linespec_location {}; - -protected: - - explicit linespec_location_spec (const linespec_location_spec *to_clone) - : 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 - { - if (linespec_location.spec_string != nullptr) - { - const struct linespec_location *ls = &linespec_location; - if (ls->match_type == symbol_name_match_type::FULL) - return std::string ("-qualified ") + ls->spec_string; - else - return ls->spec_string; - } - return {}; - } -}; - -/* An address in the inferior. */ -struct address_location_spec : public location_spec + if (*linespec != NULL) + { + const char *p; + const char *orig = *linespec; + + linespec_lex_to_end (linespec); + p = remove_trailing_whitespace (orig, *linespec); + + /* If there is no valid linespec then this will leave the + spec_string as nullptr. This behaviour is relied on in the + breakpoint setting code, where spec_string being nullptr means + to use the default breakpoint location. */ + if ((p - orig) > 0) + spec_string = savestring (orig, p - orig); + } +} + +linespec_location_spec::~linespec_location_spec () { - address_location_spec (CORE_ADDR addr, const char *addr_string, - int addr_string_len) - : location_spec (ADDRESS_LOCATION_SPEC), - address (addr) - { - if (addr_string != nullptr) - as_string = std::string (addr_string, addr_string_len); - } - - location_spec_up clone () const override - { - return location_spec_up (new address_location_spec (this)); - } - - bool empty_p () const override - { - return false; - } - - CORE_ADDR address; - -protected: - - address_location_spec (const address_location_spec *to_clone) - : location_spec (to_clone), - address (to_clone->address) - { - } - - std::string compute_string () const override - { - const char *addr_string = core_addr_to_string (address); - return std::string ("*") + addr_string; - } -}; - -/* An explicit location spec. */ -struct explicit_location_spec : public location_spec + xfree (spec_string); +} + +location_spec_up +linespec_location_spec::clone () const { - explicit explicit_location_spec (const struct explicit_location *loc) - : location_spec (EXPLICIT_LOCATION_SPEC) - { - copy_loc (loc); - } - - ~explicit_location_spec () - { - xfree (explicit_loc.source_filename); - xfree (explicit_loc.function_name); - xfree (explicit_loc.label_name); - } - - location_spec_up clone () const override - { - return location_spec_up (new explicit_location_spec (this)); - } - - bool empty_p () const override - { - return (explicit_loc.source_filename == nullptr - && explicit_loc.function_name == nullptr - && explicit_loc.label_name == nullptr - && explicit_loc.line_offset.sign == LINE_OFFSET_UNKNOWN); - } - - struct explicit_location explicit_loc; - -protected: - - explicit explicit_location_spec (const explicit_location_spec *to_clone) - : location_spec (to_clone) - { - copy_loc (&to_clone->explicit_loc); - } - - std::string compute_string () const override - { - return explicit_location_to_string (&explicit_loc); - } - -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; - } - } -}; + return location_spec_up (new linespec_location_spec (*this)); +} -/* See description in location.h. */ +bool +linespec_location_spec::empty_p () const +{ + return false; +} -enum location_spec_type -location_spec_type (const location_spec *locspec) +linespec_location_spec::linespec_location_spec + (const linespec_location_spec &other) + : location_spec (other), + match_type (other.match_type), + spec_string (maybe_xstrdup (other.spec_string)) { - return locspec->type; +} + +std::string +linespec_location_spec::compute_string () const +{ + if (spec_string != nullptr) + { + if (match_type == symbol_name_match_type::FULL) + return std::string ("-qualified ") + spec_string; + else + return spec_string; + } + return {}; +} + +address_location_spec::address_location_spec (CORE_ADDR addr, + const char *addr_string, + int addr_string_len) + : location_spec (ADDRESS_LOCATION_SPEC), + address (addr) +{ + if (addr_string != nullptr) + as_string = std::string (addr_string, addr_string_len); +} + +location_spec_up +address_location_spec::clone () const +{ + return location_spec_up (new address_location_spec (*this)); +} + +bool +address_location_spec::empty_p () const +{ + return false; +} + +address_location_spec::address_location_spec + (const address_location_spec &other) + : location_spec (other), + address (other.address) +{ +} + +std::string +address_location_spec::compute_string () const +{ + const char *addr_string = core_addr_to_string (address); + return std::string ("*") + addr_string; +} + +explicit_location_spec::explicit_location_spec () + : location_spec (EXPLICIT_LOCATION_SPEC) +{ +} + +explicit_location_spec::~explicit_location_spec () +{ + xfree (source_filename); + xfree (function_name); + xfree (label_name); +} + +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) +{ +} + +location_spec_up +explicit_location_spec::clone () const +{ + return location_spec_up (new explicit_location_spec (*this)); +} + +bool +explicit_location_spec::empty_p () const +{ + return (source_filename == nullptr + && function_name == nullptr + && label_name == nullptr + && line_offset.sign == LINE_OFFSET_UNKNOWN); +} + +std::string +explicit_location_spec::compute_string () const +{ + return explicit_to_string_internal (false, this); } /* See description in location.h. */ -void -initialize_explicit_location (struct explicit_location *explicit_loc) +enum location_spec_type +location_spec_type (const location_spec *locspec) { - 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; + return locspec->type; } /* See description in location.h. */ @@ -317,11 +224,11 @@ new_linespec_location_spec (const char **linespec, /* See description in location.h. */ -const linespec_location * -get_linespec_location (const location_spec *locspec) +const linespec_location_spec * +as_linespec_location_spec (const location_spec *locspec) { gdb_assert (locspec->type == LINESPEC_LOCATION_SPEC); - return &((linespec_location_spec *) locspec)->linespec_location; + return static_cast (locspec); } /* 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. */ -CORE_ADDR -get_address_location (const location_spec *locspec) +const address_location_spec * +as_address_location_spec (const location_spec *locspec) { gdb_assert (locspec->type == ADDRESS_LOCATION_SPEC); - return ((address_location_spec *) locspec)->address; -} - -/* 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 (); + return static_cast (locspec); } /* See description in location.h. */ @@ -362,37 +260,29 @@ new_probe_location_spec (std::string &&probe) /* See description in location.h. */ -const char * -get_probe_location_spec_string (const location_spec *locspec) +const probe_location_spec * +as_probe_location_spec (const location_spec *locspec) { gdb_assert (locspec->type == PROBE_LOCATION_SPEC); - return locspec->to_string (); -} - -/* See description in location.h. */ - -location_spec_up -new_explicit_location_spec (const explicit_location *explicit_loc) -{ - return location_spec_up (new explicit_location_spec (explicit_loc)); + return static_cast (locspec); } /* See description in location.h. */ -struct explicit_location * -get_explicit_location (location_spec *locspec) +const explicit_location_spec * +as_explicit_location_spec (const location_spec *locspec) { gdb_assert (locspec->type == EXPLICIT_LOCATION_SPEC); - return &((explicit_location_spec *) locspec)->explicit_loc; + return static_cast (locspec); } /* See description in location.h. */ -const struct explicit_location * -get_explicit_location_const (const location_spec *locspec) +explicit_location_spec * +as_explicit_location_spec (location_spec *locspec) { gdb_assert (locspec->type == EXPLICIT_LOCATION_SPEC); - return &((explicit_location_spec *) locspec)->explicit_loc; + return static_cast (locspec); } /* 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 explicit_to_string_internal (bool as_linespec, - const struct explicit_location *explicit_loc) + const explicit_location_spec *explicit_loc) { bool need_space = false; char space = as_linespec ? ':' : ' '; @@ -457,18 +347,10 @@ explicit_to_string_internal (bool as_linespec, /* 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 -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. */ @@ -479,12 +361,6 @@ copy_location_spec (const location_spec *src) return src->clone (); } -void -location_spec_deleter::operator() (location_spec *locspec) const -{ - delete locspec; -} - /* See description in location.h. */ const char * @@ -788,7 +664,7 @@ string_to_explicit_location_spec (const char **argp, return NULL; std::unique_ptr locspec - (new explicit_location_spec ((const explicit_location *) nullptr)); + (new explicit_location_spec ()); /* Process option/argument pairs. dprintf_command 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, completion_info)); - locspec->explicit_loc.source_filename = oarg.release (); + locspec->source_filename = oarg.release (); } else if (strncmp (opt.get (), "-function", len) == 0) { set_oarg (explicit_location_spec_lex_one_function (argp, language, completion_info)); - locspec->explicit_loc.function_name = oarg.release (); + locspec->function_name = oarg.release (); } else if (strncmp (opt.get (), "-qualified", len) == 0) { - locspec->explicit_loc.func_name_match_type - = symbol_name_match_type::FULL; + locspec->func_name_match_type = symbol_name_match_type::FULL; } else if (strncmp (opt.get (), "-line", len) == 0) { @@ -876,8 +751,7 @@ string_to_explicit_location_spec (const char **argp, *argp = skip_spaces (*argp); if (have_oarg) { - locspec->explicit_loc.line_offset - = linespec_parse_line_offset (oarg.get ()); + locspec->line_offset = linespec_parse_line_offset (oarg.get ()); continue; } } @@ -885,7 +759,7 @@ string_to_explicit_location_spec (const char **argp, { set_oarg (explicit_location_spec_lex_one (argp, language, completion_info)); - locspec->explicit_loc.label_name = oarg.release (); + locspec->label_name = oarg.release (); } /* Only emit an "invalid argument" error for options 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 without offset, function, or label, issue an error. */ - if (locspec->explicit_loc.source_filename != NULL - && locspec->explicit_loc.function_name == NULL - && locspec->explicit_loc.label_name == NULL - && (locspec->explicit_loc.line_offset.sign == LINE_OFFSET_UNKNOWN) + if (locspec->source_filename != NULL + && locspec->function_name == NULL + && locspec->label_name == NULL + && (locspec->line_offset.sign == LINE_OFFSET_UNKNOWN) && completion_info == NULL) { error (_("Source filename requires function, label, or " @@ -1000,7 +874,7 @@ string_to_location_spec (const char **stringp, explicit_location_spec *xloc = dynamic_cast (locspec.get ()); 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 diff --git a/gdb/location.h b/gdb/location.h index 602998de298..0a2f1799bc4 100644 --- a/gdb/location.h +++ b/gdb/location.h @@ -46,8 +46,8 @@ enum offset_relative_sign struct line_offset { /* Line offset and any specified sign. */ - int offset; - enum offset_relative_sign sign; + int offset = 0; + enum offset_relative_sign sign = LINE_OFFSET_UNKNOWN; }; /* An enumeration of the various ways to specify a location spec. */ @@ -67,15 +67,104 @@ enum location_spec_type PROBE_LOCATION_SPEC }; -/* A traditional linespec. */ +/* A unique pointer for location_spec. */ +typedef std::unique_ptr location_spec_up; + +/* The base class for all location specs used to resolve actual + locations in the inferior. */ -struct linespec_location +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. */ symbol_name_match_type match_type; /* 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 @@ -83,24 +172,58 @@ struct linespec_location as linespecs, though. For example, source_filename requires 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. */ - char *source_filename; + char *source_filename = nullptr; /* The function name. Malloc'd. */ - char *function_name; + char *function_name = nullptr; /* 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. */ - char *label_name; + char *label_name = nullptr; /* A line offset relative to the start of the symbol identified by the above fields or the current symtab 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. */ @@ -108,13 +231,6 @@ struct explicit_location extern enum location_spec_type 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. This function may return NULL for unspecified linespecs, e.g, LINESPEC_LOCATION_SPEC and spec_string is NULL. @@ -124,27 +240,16 @@ extern std::string explicit_location_to_linespec extern const char * 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_up; - /* Create a new linespec location spec. */ extern location_spec_up new_linespec_location_spec (const char **linespec, symbol_name_match_type match_type); -/* Return the linespec location spec of the given location_spec (which - must be of type LINESPEC_LOCATION_SPEC). */ +/* Return the given location_spec as a linespec_location_spec. + LOCSPEC must be of type LINESPEC_LOCATION_SPEC. */ -extern const linespec_location * - get_linespec_location (const location_spec *locspec); +extern const linespec_location_spec * + as_linespec_location_spec (const location_spec *locspec); /* Create a new address 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, int addr_string_len); -/* Return the address (a CORE_ADDR) of the given location_spec, which - must be of type ADDRESS_LOCATION_SPEC. */ - -extern CORE_ADDR - get_address_location (const location_spec *locspec); +/* Return the given location_spec as an address_location_spec. + LOCSPEC must be of type ADDRESS_LOCATION_SPEC. */ -/* 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); +const address_location_spec * + as_address_location_spec (const location_spec *locspec); /* Create a new probe location. */ extern location_spec_up new_probe_location_spec (std::string &&probe); -/* Return the probe location spec string of the given location_spec, - which must be of type PROBE_LOCATION_SPEC. */ - -extern const char * - get_probe_location_spec_string (const location_spec *locspec); - -/* Initialize the given explicit location. */ +/* Assuming LOCSPEC is of type PROBE_LOCATION_SPEC, return LOCSPEC + cast to probe_location_spec. */ -extern void - initialize_explicit_location (explicit_location *locspec); +const probe_location_spec * + as_probe_location_spec (const location_spec *locspec); -/* Create a new explicit location. If not NULL, EXPLICIT is checked for - validity. If invalid, an exception is thrown. */ +/* Create a new explicit location with explicit FUNCTION_NAME. All + other fields are defaulted. */ -extern location_spec_up - new_explicit_location_spec (const explicit_location *locspec); - -/* Return the explicit location spec of the given location_spec, which - 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); +static inline location_spec_up +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); +} + +/* Assuming LOCSPEC is of type EXPLICIT_LOCATION_SPEC, return LOCSPEC + cast to explicit_location_spec. */ + +const explicit_location_spec * + as_explicit_location_spec (const location_spec *locspec); +explicit_location_spec * + as_explicit_location_spec (location_spec *locspec); /* Return a copy of the given SRC location spec. */ diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c index dab0a471abc..408f582ebc5 100644 --- a/gdb/mi/mi-cmd-break.c +++ b/gdb/mi/mi-cmd-break.c @@ -182,7 +182,8 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc) location_spec_up locspec; const struct breakpoint_ops *ops; int is_explicit = 0; - struct explicit_location explicit_loc; + std::unique_ptr explicit_loc + (new explicit_location_spec ()); std::string extra_string; 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; char *oarg; - initialize_explicit_location (&explicit_loc); - while (1) { 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; case EXPLICIT_SOURCE_OPT: is_explicit = 1; - explicit_loc.source_filename = oarg; + explicit_loc->source_filename = xstrdup (oarg); break; case EXPLICIT_FUNC_OPT: is_explicit = 1; - explicit_loc.function_name = oarg; + explicit_loc->function_name = xstrdup (oarg); break; case EXPLICIT_LABEL_OPT: is_explicit = 1; - explicit_loc.label_name = oarg; + explicit_loc->label_name = xstrdup (oarg); break; case EXPLICIT_LINE_OPT: is_explicit = 1; - explicit_loc.line_offset = linespec_parse_line_offset (oarg); + explicit_loc->line_offset = linespec_parse_line_offset (oarg); break; case FORCE_CONDITION_OPT: 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 parameters specified. */ - if (explicit_loc.source_filename != NULL - && explicit_loc.function_name == NULL - && explicit_loc.label_name == NULL - && explicit_loc.line_offset.sign == LINE_OFFSET_UNKNOWN) + if (explicit_loc->source_filename != NULL + && explicit_loc->function_name == NULL + && explicit_loc->label_name == NULL + && explicit_loc->line_offset.sign == LINE_OFFSET_UNKNOWN) error (_("-%s-insert: --source option requires --function, --label," " 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 { diff --git a/gdb/probe.c b/gdb/probe.c index 0b056eb88db..5371b7eca46 100644 --- a/gdb/probe.c +++ b/gdb/probe.c @@ -123,7 +123,7 @@ parse_probes (const location_spec *locspec, const char *arg_start, *cs; 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; const static_probe_ops *spops = probe_linespec_to_static_ops (&cs); diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c index 029ced74136..bab1c60a43e 100644 --- a/gdb/python/py-breakpoint.c +++ b/gdb/python/py-breakpoint.c @@ -839,20 +839,23 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs) } else { - struct explicit_location explicit_loc; + std::unique_ptr explicit_loc + (new explicit_location_spec ()); - initialize_explicit_location (&explicit_loc); - explicit_loc.source_filename = source; - explicit_loc.function_name = function; - explicit_loc.label_name = label; + explicit_loc->source_filename + = source != nullptr ? xstrdup (source) : nullptr; + explicit_loc->function_name + = function != nullptr ? xstrdup (function) : nullptr; + explicit_loc->label_name + = label != nullptr ? xstrdup (label) : nullptr; if (line != NULL) - explicit_loc.line_offset = - linespec_parse_line_offset (line.get ()); + explicit_loc->line_offset + = 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