aboutsummaryrefslogtreecommitdiff
path: root/gdb/linespec.c
diff options
context:
space:
mode:
authorKeith Seitz <keiths@redhat.com>2015-08-11 17:09:35 -0700
committerKeith Seitz <keiths@redhat.com>2015-08-11 17:09:35 -0700
commitf00aae0f7b11c4dc85c38d5fad46975033ba3fff (patch)
treeb1cbb1e69fef74ac4a8716a4f3908d58b1d35fcb /gdb/linespec.c
parentc7c1b3e998a77eb077ac3c08c88a97d2e11dfef0 (diff)
downloadgdb-f00aae0f7b11c4dc85c38d5fad46975033ba3fff.zip
gdb-f00aae0f7b11c4dc85c38d5fad46975033ba3fff.tar.gz
gdb-f00aae0f7b11c4dc85c38d5fad46975033ba3fff.tar.bz2
Explicit locations: use new location API
This patch converts the code base to use the new struct event_location API being introduced. This patch preserves the current functionality and adds no new features. The "big picture" API usage introduced by this patch may be illustrated with a simple exmaple. Where previously developers would write: void my_command (char *arg, int from_tty) { create_breakpoint (..., arg, ...); ... } one now uses: void my_command (char *arg, int from_tty) { struct event_locaiton *location; struct cleanup *back_to; location = string_to_event_locaiton (&arg, ...); back_to = make_cleanup_delete_event_location (location); create_breakpoint (..., location, ...); do_cleanups (back_to); } Linespec-decoding functions (now called location-decoding) such as decode_line_full no longer skip argument pointers over processed input. That functionality has been moved into string_to_event_location as demonstrated above. gdb/ChangeLog * ax-gdb.c: Include location.h. (agent_command_1) Use linespec location instead of address string. * break-catch-throw.c: Include location.h. (re_set_exception_catchpoint): Use linespec locations instead of address strings. * breakpoint.c: Include location.h. (create_overlay_event_breakpoint, create_longjmp_master_breakpoint) (create_std_terminate_master_breakpoint) (create_exception_master_breakpoint, update_breakpoints_after_exec): Use linespec location instead of address string. (print_breakpoint_location): Use locations and event_location_to_string. Print extra_string for pending locations for non-MI streams. (print_one_breakpoint_location): Use locations and event_location_to_string. (init_raw_breakpoint_without_location): Initialize b->location. (create_thread_event_breakpoint): Use linespec location instead of address string. (init_breakpoint_sal): Likewise. Only save extra_string if it is non-NULL and not the empty string. Use event_location_to_string instead of `addr_string'. Constify `p' and `endp'. Use skip_spaces_const/skip_space_const instead of non-const versions. Copy the location into the breakpoint. If LOCATION is NULL, save the breakpoint address as a linespec location instead of an address string. (create_breakpoint_sal): Change `addr_string' parameter to a struct event_location. All uses updated. (create_breakpoints_sal): Likewise for local variable `addr_string'. (parse_breakpoint_sals): Use locations instead of address strings. Remove check for empty linespec with conditional. Refactor. (decode_static_tracepoint_spec): Make argument const and update function. (create_breakpoint): Change `arg' to a struct event_location and rename. Remove `copy_arg' and `addr_start'. If EXTRA_STRING is empty, set it to NULL. Don't populate `canonical' for pending breakpoints. Pass `extra_string' to find_condition_and_thread. Clear `extra_string' if `rest' was NULL. Do not error with "garbage after location" if setting a dprintf breakpoint. Copy the location into the breakpoint instead of an address string. (break_command_1): Use string_to_event_location and pass this to create_breakpoint instead of an address string. Check against `arg_cp' for a probe linespec. (dprintf_command): Use string_to_event_location and pass this to create_breakpoint instead of an address string. Throw an exception if no format string was specified. (print_recreate_ranged_breakpoint): Use event_location_to_string instead of address strings. (break_range_command, until_break_command) (init_ada_exception_breakpoint): Use locations instead of address strings. (say_where): Print out extra_string for pending locations. (base_breakpoint_dtor): Delete `location' and `location_range_end' of the breakpoint. (base_breakpoint_create_sals_from_location): Use struct event_location instead of address string. Remove `addr_start' and `copy_arg' parameters. (base_breakpoint_decode_location): Use struct event_location instead of address string. (bkpt_re_set): Use locations instead of address strings. Use event_location_empty_p to check for unset location. (bkpt_print_recreate): Use event_location_to_string instead of an address string. Print out extra_string for pending locations. (bkpt_create_sals_from_location, bkpt_decode_location) (bkpt_probe_create_sals_from_location): Use struct event_location instead of address string. (bkpt_probe_decode_location): Use struct event_location instead of address string. (tracepoint_print_recreate): Use event_location_to_string to recreate the tracepoint. (tracepoint_create_sals_from_location, tracepoint_decode_location) (tracepoint_probe_create_sals_from_location) (tracepoint_probe_decode_location): Use struct event_location instead of address string. (dprintf_print_recreate): Use event_location_to_string to recreate the dprintf. (dprintf_re_set): Remove check for valid/missing format string. (strace_marker_create_sals_from_location) (strace_marker_create_breakpoints_sal, strace_marker_decode_location) (update_static_tracepoint): Use struct event_location instead of address string. (location_to_sals): Likewise. Pass `extra_string' to find_condition_and_thread. For newly resolved pending breakpoint locations, clear the location's string representation. Assert that the breakpoint's condition string is NULL when condition_not_parsed. (breakpoint_re_set_default, create_sals_from_location_default) (decode_location_default, trace_command, ftrace_command) (strace_command, create_tracepoint_from_upload): Use locations instead of address strings. * breakpoint.h (struct breakpoint_ops) <create_sals_from_location>: Use struct event_location instead of address string. Update all uses. <decode_location>: Likewise. (struct breakpoint) <addr_string>: Change to struct event_location and rename `location'. <addr_string_range_end>: Change to struct event_location and rename `location_range_end'. (create_breakpoint): Use struct event_location instead of address string. * cli/cli-cmds.c: Include location.h. (edit_command, list_command): Use locations instead of address strings. * elfread.c: Include location.h. (elf_gnu_ifunc_resolver_return_stop): Use event_location_to_string. * guile/scm-breakpoint.c: Include location.h. (bpscm_print_breakpoint_smob): Use event_location_to_string. (gdbscm_register_breakpoint): Use locations instead of address strings. * linespec.c: Include location.h. (struct ls_parser) <stream>: Change to const char *. (PARSER_STREAM): Update. (lionespec_lexer_lex_keyword): According to find_condition_and_thread, keywords must be followed by whitespace. (canonicalize_linespec): Save a linespec location into `canonical'. Save a canonical linespec into `canonical'. (parse_linespec): Change `argptr' to const char * and rename `arg'. All uses updated. Update function description. (linespec_parser_new): Initialize `parser'. Update initialization of parsing stream. (event_location_to_sals): New function. (decode_line_full): Change `argptr' to a struct event_location and rename it `location'. Use locations instead of address strings. Call event_location_to_sals instead of parse_linespec. (decode_line_1): Likewise. (decode_line_with_current_source, decode_line_with_last_displayed) Use locations instead of address strings. (decode_objc): Likewise. Change `argptr' to const char * and rename `arg'. (destroy_linespec_result): Delete the linespec result's location instead of freeing the address string. * linespec.h (struct linespec_result) <addr_string>: Change to struct event_location and rename to ... <location>: ... this. (decode_line_1, decode_line_full): Change `argptr' to struct event_location. All callers updated. * mi/mi-cmd-break.c: Include language.h, location.h, and linespec.h. (mi_cmd_break_insert_1): Use locations instead of address strings. Throw an error if there was "garbage" at the end of the specified linespec. * probe.c: Include location.h. (parse_probes): Change `argptr' to struct event_location. Use event locations instead of address strings. * probe.h (parse_probes): Change `argptr' to struct event_location. * python/py-breakpoint.c: Include location.h. (bppy_get_location): Constify local variable `str'. Use event_location_to_string. (bppy_init): Use locations instead of address strings. * python/py-finishbreakpoint.c: Include location.h. (bpfinishpy_init): Remove local variable `addr_str'. Use locations instead of address strings. * python/python.c: Include location.h. (gdbpy_decode_line): Use locations instead of address strings. * remote.c: Include location.h. (remote_download_tracepoint): Use locations instead of address strings. * spu-tdep.c: Include location.h. (spu_catch_start): Remove local variable `buf'. Use locations instead of address strings. * tracepoint.c: Include location.h. (scope_info): Use locations instead of address strings. (encode_source_string): Constify parameter `src'. * tracepoint.h (encode_source_string): Likewise. gdb/testsuite/ChangeLog * gdb.base/dprintf-pending.exp: Update dprintf "without format" test. Add tests for missing ",FMT" and ",".
Diffstat (limited to 'gdb/linespec.c')
-rw-r--r--gdb/linespec.c142
1 files changed, 97 insertions, 45 deletions
diff --git a/gdb/linespec.c b/gdb/linespec.c
index 5c4ed3f..7cebe39 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -43,6 +43,7 @@
#include "filenames.h"
#include "ada-lang.h"
#include "stack.h"
+#include "location.h"
typedef struct symbol *symbolp;
DEF_VEC_P (symbolp);
@@ -281,8 +282,8 @@ struct ls_parser
const char *saved_arg;
/* Head of the input stream. */
- const char **stream;
-#define PARSER_STREAM(P) (*(P)->lexer.stream)
+ const char *stream;
+#define PARSER_STREAM(P) ((P)->lexer.stream)
/* The current token. */
linespec_token current;
@@ -315,7 +316,7 @@ static CORE_ADDR linespec_expression_to_pc (const char **exp_ptr);
static struct symtabs_and_lines decode_objc (struct linespec_state *self,
linespec_p ls,
- const char **argptr);
+ const char *arg);
static VEC (symtab_ptr) *symtabs_from_filename (const char *);
@@ -1785,21 +1786,29 @@ linespec_parse_basic (linespec_parser *parser)
STATE->canonical. */
static void
-canonicalize_linespec (struct linespec_state *state, linespec_p ls)
+canonicalize_linespec (struct linespec_state *state, const linespec_p ls)
{
+ char *tmp;
+
/* If canonicalization was not requested, no need to do anything. */
if (!state->canonical)
return;
/* Shortcut expressions, which can only appear by themselves. */
if (ls->expression != NULL)
- state->canonical->addr_string = xstrdup (ls->expression);
+ {
+ tmp = ASTRDUP (ls->expression);
+ state->canonical->location = new_linespec_location (&tmp);
+ }
else
{
struct ui_file *buf;
int need_colon = 0;
+ struct cleanup *cleanup;
buf = mem_fileopen ();
+ cleanup = make_cleanup_ui_file_delete (buf);
+
if (ls->source_filename)
{
fputs_unfiltered (ls->source_filename, buf);
@@ -1848,8 +1857,10 @@ canonicalize_linespec (struct linespec_state *state, linespec_p ls)
ls->line_offset.offset);
}
- state->canonical->addr_string = ui_file_xstrdup (buf, NULL);
- ui_file_delete (buf);
+ tmp = ui_file_xstrdup (buf, NULL);
+ make_cleanup (xfree, tmp);
+ state->canonical->location = new_linespec_location (&tmp);
+ do_cleanups (cleanup);
}
}
@@ -2117,8 +2128,6 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
}
/* Parse a string that specifies a linespec.
- Pass the address of a char * variable; that variable will be
- advanced over the characters actually parsed.
The basic grammar of linespecs:
@@ -2167,10 +2176,10 @@ convert_linespec_to_sals (struct linespec_state *state, linespec_p ls)
if no file is validly specified. Callers must check that.
Also, the line number returned may be invalid. */
-/* Parse the linespec in ARGPTR. */
+/* Parse the linespec in ARG. */
static struct symtabs_and_lines
-parse_linespec (linespec_parser *parser, const char **argptr)
+parse_linespec (linespec_parser *parser, const char *arg)
{
linespec_token token;
struct symtabs_and_lines values;
@@ -2181,30 +2190,30 @@ parse_linespec (linespec_parser *parser, const char **argptr)
IDEs to work around bugs in the previous parser by quoting
the entire linespec, so we attempt to deal with this nicely. */
parser->is_quote_enclosed = 0;
- if (!is_ada_operator (*argptr)
- && strchr (linespec_quote_characters, **argptr) != NULL)
+ if (!is_ada_operator (arg)
+ && strchr (linespec_quote_characters, *arg) != NULL)
{
const char *end;
- end = skip_quote_char (*argptr + 1, **argptr);
+ end = skip_quote_char (arg + 1, *arg);
if (end != NULL && is_closing_quote_enclosed (end))
{
- /* Here's the special case. Skip ARGPTR past the initial
+ /* Here's the special case. Skip ARG past the initial
quote. */
- ++(*argptr);
+ ++arg;
parser->is_quote_enclosed = 1;
}
}
- parser->lexer.saved_arg = *argptr;
- parser->lexer.stream = argptr;
+ parser->lexer.saved_arg = arg;
+ parser->lexer.stream = arg;
/* Initialize the default symtab and line offset. */
initialize_defaults (&PARSER_STATE (parser)->default_symtab,
&PARSER_STATE (parser)->default_line);
/* Objective-C shortcut. */
- values = decode_objc (PARSER_STATE (parser), PARSER_RESULT (parser), argptr);
+ values = decode_objc (PARSER_STATE (parser), PARSER_RESULT (parser), arg);
if (values.sals != NULL)
return values;
@@ -2390,6 +2399,7 @@ linespec_parser_new (linespec_parser *parser,
int default_line,
struct linespec_result *canonical)
{
+ memset (parser, 0, sizeof (linespec_parser));
parser->lexer.current.type = LSTOKEN_CONSUMED;
memset (PARSER_RESULT (parser), 0, sizeof (struct linespec));
PARSER_RESULT (parser)->line_offset.sign = LINE_OFFSET_UNKNOWN;
@@ -2443,7 +2453,6 @@ linespec_lex_to_end (char **stringp)
linespec_parser parser;
struct cleanup *cleanup;
linespec_token token;
- volatile struct gdb_exception e;
const char *orig;
if (stringp == NULL || *stringp == NULL)
@@ -2483,10 +2492,42 @@ linespec_lex_to_end (char **stringp)
do_cleanups (cleanup);
}
+/* A helper function for decode_line_full and decode_line_1 to
+ turn LOCATION into symtabs_and_lines. */
+
+static struct symtabs_and_lines
+event_location_to_sals (linespec_parser *parser,
+ const struct event_location *location)
+{
+ struct symtabs_and_lines result = {NULL, 0};
+
+ switch (event_location_type (location))
+ {
+ case LINESPEC_LOCATION:
+ {
+ TRY
+ {
+ result = parse_linespec (parser, get_linespec_location (location));
+ }
+ CATCH (except, RETURN_MASK_ERROR)
+ {
+ throw_exception (except);
+ }
+ END_CATCH
+ }
+ break;
+
+ default:
+ gdb_assert_not_reached ("unhandled event location type");
+ }
+
+ return result;
+}
+
/* See linespec.h. */
void
-decode_line_full (char **argptr, int flags,
+decode_line_full (const struct event_location *location, int flags,
struct symtab *default_symtab,
int default_line, struct linespec_result *canonical,
const char *select_mode,
@@ -2497,7 +2538,6 @@ decode_line_full (char **argptr, int flags,
VEC (const_char_ptr) *filters = NULL;
linespec_parser parser;
struct linespec_state *state;
- const char *copy, *orig;
gdb_assert (canonical != NULL);
/* The filter only makes sense for 'all'. */
@@ -2513,13 +2553,10 @@ decode_line_full (char **argptr, int flags,
cleanups = make_cleanup (linespec_parser_delete, &parser);
save_current_program_space ();
- orig = copy = *argptr;
- result = parse_linespec (&parser, &copy);
- *argptr += copy - orig;
+ result = event_location_to_sals (&parser, location);
state = PARSER_STATE (&parser);
gdb_assert (result.nelts == 1 || canonical->pre_expanded);
- gdb_assert (canonical->addr_string != NULL);
canonical->pre_expanded = 1;
/* Arrange for allocated canonical names to be freed. */
@@ -2563,23 +2600,20 @@ decode_line_full (char **argptr, int flags,
/* See linespec.h. */
struct symtabs_and_lines
-decode_line_1 (char **argptr, int flags,
+decode_line_1 (const struct event_location *location, int flags,
struct symtab *default_symtab,
int default_line)
{
struct symtabs_and_lines result;
linespec_parser parser;
struct cleanup *cleanups;
- const char *copy, *orig;
linespec_parser_new (&parser, flags, current_language, default_symtab,
default_line, NULL);
cleanups = make_cleanup (linespec_parser_delete, &parser);
save_current_program_space ();
- orig = copy = *argptr;
- result = parse_linespec (&parser, &copy);
- *argptr += copy - orig;
+ result = event_location_to_sals (&parser, location);
do_cleanups (cleanups);
return result;
@@ -2592,6 +2626,8 @@ decode_line_with_current_source (char *string, int flags)
{
struct symtabs_and_lines sals;
struct symtab_and_line cursal;
+ struct event_location *location;
+ struct cleanup *cleanup;
if (string == 0)
error (_("Empty line specification."));
@@ -2600,11 +2636,15 @@ decode_line_with_current_source (char *string, int flags)
and get a default source symtab+line or it will recursively call us! */
cursal = get_current_source_symtab_and_line ();
- sals = decode_line_1 (&string, flags,
+ location = string_to_event_location (&string, current_language);
+ cleanup = make_cleanup_delete_event_location (location);
+ sals = decode_line_1 (location, flags,
cursal.symtab, cursal.line);
if (*string)
error (_("Junk at end of line specification: %s"), string);
+
+ do_cleanups (cleanup);
return sals;
}
@@ -2614,19 +2654,25 @@ struct symtabs_and_lines
decode_line_with_last_displayed (char *string, int flags)
{
struct symtabs_and_lines sals;
+ struct event_location *location;
+ struct cleanup *cleanup;
if (string == 0)
error (_("Empty line specification."));
+ location = string_to_event_location (&string, current_language);
+ cleanup = make_cleanup_delete_event_location (location);
if (last_displayed_sal_is_valid ())
- sals = decode_line_1 (&string, flags,
+ sals = decode_line_1 (location, flags,
get_last_displayed_symtab (),
get_last_displayed_line ());
else
- sals = decode_line_1 (&string, flags, (struct symtab *) NULL, 0);
+ sals = decode_line_1 (location, flags, (struct symtab *) NULL, 0);
if (*string)
error (_("Junk at end of line specification: %s"), string);
+
+ do_cleanups (cleanup);
return sals;
}
@@ -2679,7 +2725,7 @@ linespec_expression_to_pc (const char **exp_ptr)
the existing C++ code to let the user choose one. */
static struct symtabs_and_lines
-decode_objc (struct linespec_state *self, linespec_p ls, const char **argptr)
+decode_objc (struct linespec_state *self, linespec_p ls, const char *arg)
{
struct collect_info info;
VEC (const_char_ptr) *symbol_names = NULL;
@@ -2697,7 +2743,7 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char **argptr)
values.nelts = 0;
values.sals = NULL;
- new_argptr = find_imps (*argptr, &symbol_names);
+ new_argptr = find_imps (arg, &symbol_names);
if (VEC_empty (const_char_ptr, symbol_names))
{
do_cleanups (cleanup);
@@ -2711,9 +2757,9 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char **argptr)
{
char *saved_arg;
- saved_arg = alloca (new_argptr - *argptr + 1);
- memcpy (saved_arg, *argptr, new_argptr - *argptr);
- saved_arg[new_argptr - *argptr] = '\0';
+ saved_arg = alloca (new_argptr - arg + 1);
+ memcpy (saved_arg, arg, new_argptr - arg);
+ saved_arg[new_argptr - arg] = '\0';
ls->function_name = xstrdup (saved_arg);
ls->function_symbols = info.result.symbols;
@@ -2722,17 +2768,23 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char **argptr)
if (self->canonical)
{
+ char *str;
+
self->canonical->pre_expanded = 1;
+
if (ls->source_filename)
- self->canonical->addr_string
- = xstrprintf ("%s:%s", ls->source_filename, saved_arg);
+ {
+ str = xstrprintf ("%s:%s",
+ ls->source_filename, saved_arg);
+ }
else
- self->canonical->addr_string = xstrdup (saved_arg);
+ str = xstrdup (saved_arg);
+
+ make_cleanup (xfree, str);
+ self->canonical->location = new_linespec_location (&str);
}
}
- *argptr = new_argptr;
-
do_cleanups (cleanup);
return values;
@@ -3830,7 +3882,7 @@ destroy_linespec_result (struct linespec_result *ls)
int i;
struct linespec_sals *lsal;
- xfree (ls->addr_string);
+ delete_event_location (ls->location);
for (i = 0; VEC_iterate (linespec_sals, ls->sals, i, lsal); ++i)
{
xfree (lsal->canonical);