From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 1551) id 661693856269; Fri, 17 Jun 2022 09:23:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 661693856269 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Pedro Alves To: gdb-cvs@sourceware.org Subject: [binutils-gdb] Eliminate the two-level data structures behind location_specs X-Act-Checkin: binutils-gdb X-Git-Author: Pedro Alves X-Git-Refname: refs/heads/master X-Git-Oldrev: 264f98902f27497f7494933628b0f5c4e117fe59 X-Git-Newrev: 40d97ee21fc3e39db73ee8f84b847a22f9d251cc Message-Id: <20220617092320.661693856269@sourceware.org> Date: Fri, 17 Jun 2022 09:23:20 +0000 (GMT) X-BeenThere: gdb-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Jun 2022 09:23:20 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3D40d97ee21fc3= e39db73ee8f84b847a22f9d251cc commit 40d97ee21fc3e39db73ee8f84b847a22f9d251cc Author: Pedro Alves Date: Fri May 27 13:13:41 2022 +0100 Eliminate the two-level data structures behind location_specs =20 Currently, there's the location_spec hierarchy, and then some location_spec subclasses have their own struct type holding all their data fields. =20 I.e., there is this: =20 location_spec explicit_location_spec linespec_location_spec address_location_spec probe_location_spec =20 and then these separate types: =20 explicit_location linespec_location =20 where: =20 explicit_location_spec has-a explicit_location linespec_location_spec has-a linespec_location =20 This patch eliminates explicit_location and linespec_location, inlining their members in the corresponding location_spec type. =20 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. =20 Some constructors that are used for cloning location_specs, like: =20 explicit explicit_location_spec (const struct explicit_location *loc) =20 ... were converted to proper copy ctors. =20 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. =20 Change-Id: Ia31ccef9382b25a52b00fa878c8df9b8cf2a6c5a Diff: --- gdb/break-catch-throw.c | 9 +- gdb/breakpoint.c | 44 ++-- gdb/completer.c | 6 +- gdb/linespec.c | 106 +++++----- gdb/location.c | 512 +++++++++++++++++------------------------= ---- gdb/location.h | 233 +++++++++++++++------ gdb/mi/mi-cmd-break.c | 25 ++- gdb/probe.c | 2 +- gdb/python/py-breakpoint.c | 21 +- 9 files changed, 452 insertions(+), 506 deletions(-) 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 - =3D ASTRDUP (exception_functions[kind].function); - location_spec_up locspec =3D new_explicit_location_spec (&explicit_loc); + location_spec_up locspec + =3D (new_explicit_location_spec_function + (exception_functions[kind].function)); sals =3D 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; =20 bp_objfile_data =3D get_breakpoint_objfile_data (objfile); =20 @@ -3388,9 +3387,7 @@ create_overlay_event_breakpoint (void) addr =3D bp_objfile_data->overlay_msym.value_address (); b =3D create_internal_breakpoint (objfile->arch (), addr, bp_overlay_event); - initialize_explicit_location (&explicit_loc); - explicit_loc.function_name =3D ASTRDUP (func_name); - b->locspec =3D new_explicit_location_spec (&explicit_loc); + b->locspec =3D new_explicit_location_spec_function (func_name); =20 if (overlay_debugging =3D=3D ovly_auto) { @@ -3473,7 +3470,6 @@ create_longjmp_master_breakpoint_names (objfile *objf= ile) struct breakpoint *b; const char *func_name; CORE_ADDR addr; - struct explicit_location explicit_loc; =20 if (msym_not_found_p (bp_objfile_data->longjmp_msym[i].minsym)) continue; @@ -3495,9 +3491,7 @@ create_longjmp_master_breakpoint_names (objfile *objf= ile) =20 addr =3D bp_objfile_data->longjmp_msym[i].value_address (); b =3D create_internal_breakpoint (gdbarch, addr, bp_longjmp_master); - initialize_explicit_location (&explicit_loc); - explicit_loc.function_name =3D ASTRDUP (func_name); - b->locspec =3D new_explicit_location_spec (&explicit_loc); + b->locspec =3D new_explicit_location_spec_function (func_name); b->enable_state =3D 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; =20 bp_objfile_data =3D get_breakpoint_objfile_data (objfile); =20 @@ -3578,9 +3571,7 @@ create_std_terminate_master_breakpoint (void) addr =3D bp_objfile_data->terminate_msym.value_address (); b =3D create_internal_breakpoint (objfile->arch (), addr, bp_std_terminate_master); - initialize_explicit_location (&explicit_loc); - explicit_loc.function_name =3D ASTRDUP (func_name); - b->locspec =3D new_explicit_location_spec (&explicit_loc); + b->locspec =3D new_explicit_location_spec_function (func_name); b->enable_state =3D bp_disabled; } } @@ -3648,7 +3639,6 @@ create_exception_master_breakpoint_hook (objfile *obj= file) struct gdbarch *gdbarch; struct breakpoint_objfile_data *bp_objfile_data; CORE_ADDR addr; - struct explicit_location explicit_loc; =20 bp_objfile_data =3D get_breakpoint_objfile_data (objfile); =20 @@ -3675,9 +3665,7 @@ create_exception_master_breakpoint_hook (objfile *obj= file) addr =3D gdbarch_convert_from_func_ptr_addr (gdbarch, addr, current_inferior ()->top_target ()); b =3D create_internal_breakpoint (gdbarch, addr, bp_exception_master); - initialize_explicit_location (&explicit_loc); - explicit_loc.function_name =3D ASTRDUP (func_name); - b->locspec =3D new_explicit_location_spec (&explicit_loc); + b->locspec =3D new_explicit_location_spec_function (func_name); b->enable_state =3D bp_disabled; =20 return true; @@ -8467,7 +8455,7 @@ parse_breakpoint_sals (location_spec *locspec, =20 if (location_spec_type (locspec) =3D=3D LINESPEC_LOCATION_SPEC) { - const char *spec =3D get_linespec_location (locspec)->spec_string; + const char *spec =3D as_linespec_location_spec (locspec)->spec_strin= g; =20 if (spec =3D=3D NULL) { @@ -8518,7 +8506,7 @@ parse_breakpoint_sals (location_spec *locspec, const char *spec =3D NULL; =20 if (location_spec_type (locspec) =3D=3D LINESPEC_LOCATION_SPEC) - spec =3D get_linespec_location (locspec)->spec_string; + spec =3D as_linespec_location_spec (locspec)->spec_string; =20 if (!cursal.symtab || (spec !=3D NULL @@ -12005,7 +11993,7 @@ strace_marker_create_sals_from_location_spec (locat= ion_spec *locspec, struct linespec_sals lsal; const char *arg_start, *arg; =20 - arg =3D arg_start =3D get_linespec_location (locspec)->spec_string; + arg =3D arg_start =3D as_linespec_location_spec (locspec)->spec_string; lsal.sals =3D decode_static_tracepoint_spec (&arg); =20 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 =3D get_linespec_location (locspec)->spec_string; + const char *s =3D as_linespec_location_spec (locspec)->spec_string; =20 std::vector sals =3D decode_static_tracepoint_spec (&s); if (sals.size () > static_trace_marker_id_idx) @@ -12381,7 +12369,6 @@ update_static_tracepoint (struct breakpoint *b, str= uct symtab_and_line sal) struct symbol *sym; struct static_tracepoint_marker *tpmarker; struct ui_out *uiout =3D current_uiout; - struct explicit_location explicit_loc; =20 tpmarker =3D &markers[0]; =20 @@ -12418,13 +12405,14 @@ update_static_tracepoint (struct breakpoint *b, s= truct symtab_and_line sal) b->loc->line_number =3D sal2.line; b->loc->symtab =3D sym !=3D NULL ? sal2.symtab : NULL; =20 - b->locspec.reset (nullptr); - initialize_explicit_location (&explicit_loc); - explicit_loc.source_filename - =3D ASTRDUP (symtab_to_filename_for_display (sal2.symtab)); - explicit_loc.line_offset.offset =3D b->loc->line_number; - explicit_loc.line_offset.sign =3D LINE_OFFSET_NONE; - b->locspec =3D new_explicit_location_spec (&explicit_loc); + std::unique_ptr els + (new explicit_location_spec ()); + els->source_filename + =3D xstrdup (symtab_to_filename_for_display (sal2.symtab)); + els->line_offset.offset =3D b->loc->line_number; + els->line_offset.sign =3D LINE_OFFSET_NONE; + + b->locspec =3D std::move (els); =20 /* 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 - =3D get_explicit_location (locspec); + const explicit_location_spec *explicit_loc + =3D as_explicit_location_spec (locspec); =20 /* True if the option expects an argument. */ bool needs_arg =3D true; @@ -1008,7 +1008,7 @@ location_completer (struct cmd_list_element *ignore, text =3D copy; =20 symbol_name_match_type match_type - =3D get_explicit_location (locspec.get ())->func_name_match_type; + =3D 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 =20 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; =20 /* The list of symtabs to search to which to limit the search. =20 @@ -342,8 +342,8 @@ struct linespec_parser struct completion_tracker *completion_tracker =3D nullptr; }; =20 -/* 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) =20 /* 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; =20 /* Save everything as an explicit location. */ - state->canonical->locspec - =3D new_explicit_location_spec (&ls->explicit_loc); - canon =3D state->canonical->locspec.get (); - explicit_loc =3D get_explicit_location (canon); + state->canonical->locspec =3D ls->explicit_loc.clone (); + explicit_location_spec *explicit_loc + =3D as_explicit_location_spec (state->canonical->locspec.get ()); =20 if (explicit_loc->label_name !=3D 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 ()); } =20 /* Given a line offset in LS, construct the relevant SALs. */ @@ -2307,17 +2302,18 @@ convert_linespec_to_sals (struct linespec_state *st= ate, linespec *ls) return sals; } =20 -/* 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. */ =20 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; =20 @@ -2382,16 +2378,17 @@ convert_explicit_location_to_linespec (struct lines= pec_state *self, /* Convert the explicit location EXPLICIT_LOC into SaLs. */ =20 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); } =20 @@ -2694,10 +2691,6 @@ linespec_state_destructor (struct linespec_state *se= lf) =20 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)); } =20 @@ -2855,12 +2848,12 @@ linespec_complete_label (completion_tracker &tracke= r, =20 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 =3D as_linespec_location_spec (locspec); PARSER_STATE (parser)->is_linespec =3D 1; - try - { - const linespec_location *ls =3D get_linespec_location (locspec); - result =3D parse_linespec (parser, - ls->spec_string, ls->match_type); - } - catch (const gdb_exception_error &except) - { - throw; - } + result =3D parse_linespec (parser, ls->spec_string, ls->match_type); } break; =20 case ADDRESS_LOCATION_SPEC: { - const char *addr_string =3D get_address_string_location (locspec); - CORE_ADDR addr =3D get_address_location (locspec); + const address_location_spec *addr_spec + =3D as_address_location_spec (locspec); + const char *addr_string =3D addr_spec->to_string (); + CORE_ADDR addr; =20 if (addr_string !=3D NULL) { @@ -3099,6 +3086,8 @@ location_spec_to_sals (linespec_parser *parser, PARSER_STATE (parser)->canonical->locspec =3D copy_location_spec (locspec); } + else + addr =3D addr_spec->address; =20 result =3D convert_address_location_to_sals (PARSER_STATE (parser), addr); @@ -3107,12 +3096,11 @@ location_spec_to_sals (linespec_parser *parser, =20 case EXPLICIT_LOCATION_SPEC: { - const struct explicit_location *explicit_loc; - - explicit_loc =3D get_explicit_location_const (locspec); - result =3D convert_explicit_location_to_sals (PARSER_STATE (parser), - PARSER_RESULT (parser), - explicit_loc); + const explicit_location_spec *explicit_locspec + =3D as_explicit_location_spec (locspec); + result =3D convert_explicit_location_spec_to_sals (PARSER_STATE (parser), + PARSER_RESULT (parser), + explicit_locspec); } break; =20 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 =20 -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. */ =20 -/* The base class for all location specs used to match actual - locations in the inferior. */ +static char * +maybe_xstrdup (const char *str) +{ + return (str !=3D nullptr ? xstrdup (str) : nullptr); +} + +probe_location_spec::probe_location_spec (std::string &&probe) + : location_spec (PROBE_LOCATION_SPEC, std::move (probe)) +{ +} =20 -struct location_spec +location_spec_up +probe_location_spec::clone () const { - virtual ~location_spec () =3D default; - - /* Clone this object. */ - virtual location_spec_up clone () const =3D 0; - - /* Return true if this location spec is empty, false otherwise. */ - virtual bool empty_p () const =3D 0; - - /* Return a string representation of this location. */ - const char *to_string () const - { - if (as_string.empty ()) - as_string =3D 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 =3D 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); +} =20 /* 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 =3D match_type; - if (*linespec !=3D NULL) - { - const char *p; - const char *orig =3D *linespec; - - linespec_lex_to_end (linespec); - p =3D 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 =3D 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 !=3D nullptr) - linespec_location.spec_string =3D xstrdup (linespec_location.spec_st= ring); - } - - std::string compute_string () const override - { - if (linespec_location.spec_string !=3D nullptr) - { - const struct linespec_location *ls =3D &linespec_location; - if (ls->match_type =3D=3D 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 !=3D NULL) + { + const char *p; + const char *orig =3D *linespec; + + linespec_lex_to_end (linespec); + p =3D 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 =3D 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 !=3D nullptr) - as_string =3D 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 =3D 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 =3D=3D nullptr - && explicit_loc.function_name =3D=3D nullptr - && explicit_loc.label_name =3D=3D nullptr - && explicit_loc.line_offset.sign =3D=3D 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 !=3D nullptr) - { - explicit_loc.func_name_match_type =3D loc->func_name_match_type; - if (loc->source_filename !=3D nullptr) - explicit_loc.source_filename =3D xstrdup (loc->source_filename); - if (loc->function_name !=3D nullptr) - explicit_loc.function_name =3D xstrdup (loc->function_name); - if (loc->label_name !=3D nullptr) - explicit_loc.label_name =3D xstrdup (loc->label_name); - explicit_loc.line_offset =3D loc->line_offset; - } - } -}; + return location_spec_up (new linespec_location_spec (*this)); +} =20 -/* See description in location.h. */ +bool +linespec_location_spec::empty_p () const +{ + return false; +} =20 -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 !=3D nullptr) + { + if (match_type =3D=3D 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 !=3D nullptr) + as_string =3D 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 =3D 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 =3D=3D nullptr + && function_name =3D=3D nullptr + && label_name =3D=3D nullptr + && line_offset.sign =3D=3D LINE_OFFSET_UNKNOWN); +} + +std::string +explicit_location_spec::compute_string () const +{ + return explicit_to_string_internal (false, this); } =20 /* See description in location.h. */ =20 -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 =3D LINE_OFFSET_UNKNOWN; - explicit_loc->func_name_match_type =3D symbol_name_match_type::WILD; + return locspec->type; } =20 /* See description in location.h. */ @@ -317,11 +224,11 @@ new_linespec_location_spec (const char **linespec, =20 /* See description in location.h. */ =20 -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 =3D=3D LINESPEC_LOCATION_SPEC); - return &((linespec_location_spec *) locspec)->linespec_location; + return static_cast (locspec); } =20 /* See description in location.h. */ @@ -336,20 +243,11 @@ new_address_location_spec (CORE_ADDR addr, const char= *addr_string, =20 /* See description in location.h. */ =20 -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 =3D=3D 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 =3D=3D ADDRESS_LOCATION_SPEC); - return locspec->to_string (); + return static_cast (locspec); } =20 /* See description in location.h. */ @@ -362,37 +260,29 @@ new_probe_location_spec (std::string &&probe) =20 /* See description in location.h. */ =20 -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 =3D=3D 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); } =20 /* See description in location.h. */ =20 -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 =3D=3D EXPLICIT_LOCATION_SPEC); - return &((explicit_location_spec *) locspec)->explicit_loc; + return static_cast (locspec); } =20 /* See description in location.h. */ =20 -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 =3D=3D EXPLICIT_LOCATION_SPEC); - return &((explicit_location_spec *) locspec)->explicit_loc; + return static_cast (locspec); } =20 /* Return a string representation of the explicit location spec in @@ -403,7 +293,7 @@ get_explicit_location_const (const location_spec *locsp= ec) =20 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 =3D false; char space =3D as_linespec ? ':' : ' '; @@ -457,18 +347,10 @@ explicit_to_string_internal (bool as_linespec, =20 /* See description in location.h. */ =20 -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_lo= c) +explicit_location_spec::to_linespec () const { - return explicit_to_string_internal (true, explicit_loc); + return explicit_to_string_internal (true, this); } =20 /* See description in location.h. */ @@ -479,12 +361,6 @@ copy_location_spec (const location_spec *src) return src->clone (); } =20 -void -location_spec_deleter::operator() (location_spec *locspec) const -{ - delete locspec; -} - /* See description in location.h. */ =20 const char * @@ -788,7 +664,7 @@ string_to_explicit_location_spec (const char **argp, return NULL; =20 std::unique_ptr locspec - (new explicit_location_spec ((const explicit_location *) nullptr)); + (new explicit_location_spec ()); =20 /* 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 =3D oarg.release (); + locspec->source_filename =3D oarg.release (); } else if (strncmp (opt.get (), "-function", len) =3D=3D 0) { set_oarg (explicit_location_spec_lex_one_function (argp, language, completion_info)); - locspec->explicit_loc.function_name =3D oarg.release (); + locspec->function_name =3D oarg.release (); } else if (strncmp (opt.get (), "-qualified", len) =3D=3D 0) { - locspec->explicit_loc.func_name_match_type - =3D symbol_name_match_type::FULL; + locspec->func_name_match_type =3D symbol_name_match_type::FULL; } else if (strncmp (opt.get (), "-line", len) =3D=3D 0) { @@ -876,8 +751,7 @@ string_to_explicit_location_spec (const char **argp, *argp =3D skip_spaces (*argp); if (have_oarg) { - locspec->explicit_loc.line_offset - =3D linespec_parse_line_offset (oarg.get ()); + locspec->line_offset =3D 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 =3D oarg.release (); + locspec->label_name =3D 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, =20 /* One special error check: If a source filename was given without offset, function, or label, issue an error. */ - if (locspec->explicit_loc.source_filename !=3D NULL - && locspec->explicit_loc.function_name =3D=3D NULL - && locspec->explicit_loc.label_name =3D=3D NULL - && (locspec->explicit_loc.line_offset.sign =3D=3D LINE_OFFSET_UNKNOW= N) + if (locspec->source_filename !=3D NULL + && locspec->function_name =3D=3D NULL + && locspec->label_name =3D=3D NULL + && (locspec->line_offset.sign =3D=3D LINE_OFFSET_UNKNOWN) && completion_info =3D=3D NULL) { error (_("Source filename requires function, label, or " @@ -1000,7 +874,7 @@ string_to_location_spec (const char **stringp, explicit_location_spec *xloc =3D dynamic_cast (locspec.get ()); gdb_assert (xloc !=3D nullptr); - match_type =3D xloc->explicit_loc.func_name_match_type; + match_type =3D xloc->func_name_match_type; } =20 /* 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 =3D 0; + enum offset_relative_sign sign =3D LINE_OFFSET_UNKNOWN; }; =20 /* An enumeration of the various ways to specify a location spec. */ @@ -67,15 +67,104 @@ enum location_spec_type PROBE_LOCATION_SPEC }; =20 -/* 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. */ =20 -struct linespec_location +struct location_spec { + virtual ~location_spec () =3D default; + + /* Clone this object. */ + virtual location_spec_up clone () const =3D 0; + + /* Return true if this location spec is empty, false otherwise. */ + virtual bool empty_p () const =3D 0; + + /* Return a string representation of this location. */ + const char *to_string () const + { + if (as_string.empty ()) + as_string =3D 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 =3D 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; =20 /* The linespec. */ - char *spec_string; + char *spec_string =3D 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; }; =20 /* 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. */ =20 -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 =3D nullptr; =20 /* The function name. Malloc'd. */ - char *function_name; + char *function_name =3D nullptr; =20 /* 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 + =3D symbol_name_match_type::WILD; =20 /* The name of a label. Malloc'd. */ - char *label_name; + char *label_name =3D nullptr; =20 /* 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 =3D {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) =3D default; + + std::string compute_string () const override; }; =20 /* 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 *); =20 -/* 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); =20 -/* 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. */ =20 extern location_spec_up new_linespec_location_spec (const char **linespec, symbol_name_match_type match_type); =20 -/* 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. */ =20 -extern const linespec_location * - get_linespec_location (const location_spec *locspec); +extern const linespec_location_spec * + as_linespec_location_spec (const location_spec *locspec); =20 /* 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 (CO= RE_ADDR addr, const char *addr_string, int addr_string_len); =20 -/* 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. */ =20 -/* 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); =20 /* Create a new probe location. */ =20 extern location_spec_up new_probe_location_spec (std::string &&probe); =20 -/* 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. */ =20 -extern void - initialize_explicit_location (explicit_location *locspec); +const probe_location_spec * + as_probe_location_spec (const location_spec *locspec); =20 -/* 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. */ =20 -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 + =3D new explicit_location_spec (); + spec->function_name + =3D (function_name !=3D 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); =20 /* Return a copy of the given SRC location spec. */ =20 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 =3D 0; - struct explicit_location explicit_loc; + std::unique_ptr explicit_loc + (new explicit_location_spec ()); std::string extra_string; bool force_condition =3D false; =20 @@ -220,8 +221,6 @@ mi_cmd_break_insert_1 (int dprintf, const char *command= , char **argv, int argc) int oind =3D 0; char *oarg; =20 - initialize_explicit_location (&explicit_loc); - while (1) { int opt =3D mi_getopt ("-break-insert", argc, argv, @@ -259,19 +258,19 @@ mi_cmd_break_insert_1 (int dprintf, const char *comma= nd, char **argv, int argc) break; case EXPLICIT_SOURCE_OPT: is_explicit =3D 1; - explicit_loc.source_filename =3D oarg; + explicit_loc->source_filename =3D xstrdup (oarg); break; case EXPLICIT_FUNC_OPT: is_explicit =3D 1; - explicit_loc.function_name =3D oarg; + explicit_loc->function_name =3D xstrdup (oarg); break; case EXPLICIT_LABEL_OPT: is_explicit =3D 1; - explicit_loc.label_name =3D oarg; + explicit_loc->label_name =3D xstrdup (oarg); break; case EXPLICIT_LINE_OPT: is_explicit =3D 1; - explicit_loc.line_offset =3D linespec_parse_line_offset (oarg); + explicit_loc->line_offset =3D linespec_parse_line_offset (oarg); break; case FORCE_CONDITION_OPT: force_condition =3D true; @@ -339,16 +338,16 @@ mi_cmd_break_insert_1 (int dprintf, const char *comma= nd, char **argv, int argc) { /* Error check -- we must have one of the other parameters specified. */ - if (explicit_loc.source_filename !=3D NULL - && explicit_loc.function_name =3D=3D NULL - && explicit_loc.label_name =3D=3D NULL - && explicit_loc.line_offset.sign =3D=3D LINE_OFFSET_UNKNOWN) + if (explicit_loc->source_filename !=3D NULL + && explicit_loc->function_name =3D=3D NULL + && explicit_loc->label_name =3D=3D NULL + && explicit_loc->line_offset.sign =3D=3D LINE_OFFSET_UNKNOWN) error (_("-%s-insert: --source option requires --function, --label," " or --line"), dprintf ? "dprintf" : "break"); =20 - explicit_loc.func_name_match_type =3D match_type; + explicit_loc->func_name_match_type =3D match_type; =20 - locspec =3D new_explicit_location_spec (&explicit_loc); + locspec =3D 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; =20 gdb_assert (location_spec_type (locspec) =3D=3D PROBE_LOCATION_SPEC); - arg_start =3D get_probe_location_spec_string (locspec); + arg_start =3D locspec->to_string (); =20 cs =3D arg_start; const static_probe_ops *spops =3D 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 ()); =20 - initialize_explicit_location (&explicit_loc); - explicit_loc.source_filename =3D source; - explicit_loc.function_name =3D function; - explicit_loc.label_name =3D label; + explicit_loc->source_filename + =3D source !=3D nullptr ? xstrdup (source) : nullptr; + explicit_loc->function_name + =3D function !=3D nullptr ? xstrdup (function) : nullptr; + explicit_loc->label_name + =3D label !=3D nullptr ? xstrdup (label) : nullptr; =20 if (line !=3D NULL) - explicit_loc.line_offset =3D - linespec_parse_line_offset (line.get ()); + explicit_loc->line_offset + =3D linespec_parse_line_offset (line.get ()); =20 - explicit_loc.func_name_match_type =3D func_name_match_type; + explicit_loc->func_name_match_type =3D func_name_match_type; =20 - locspec =3D new_explicit_location_spec (&explicit_loc); + locspec.reset (explicit_loc.release ()); } =20 const struct breakpoint_ops *ops