Explicit locations: introduce explicit locations

This patch add support for explicit locations and switches many linespec
locations to this new location type.  This patch also converts all
linespec locations entered by the user to an explicit representation
internally (thus bypassing the linespec parser when resetting the
breakpoint).

This patch does not introduce any user-visible changes.


gdb/ChangeLog:

	* break-catch-throw.c (re_set_exception_catchpoint): Convert
	linespec into explicit location.
	* breakpoint.c (create_overlay_breakpoint)
	(create_longjmp_master_breakpoint)
	(create_std_terminate_master_breakpoint)
	(create_exception_master_breakpoint): Convert linespec into explicit
	location.
	(update_static_tracepoint): Convert linespec into explicit location.
	* linespec.c (enum offset_relative_sign, struct line_offset): Move
	location.h.
	(struct linespec) <expression, expr_pc, source_filename>
	<function_name, label_name, line_offset>: Replace with ...
	<explicit>: ... this.
	<is_linespec>: New member.
	(PARSER_EXPLICIT): New accessor macro.
	(undefined_label_error): New function.
	(source_file_not_found_error): New function.
	(linespec_parse_basic): The parser result is now an explicit location.
	Use PARSER_EXPLICIT to access it.
	Use undefined_label_error.
	(canonicalize_linespec): Convert canonical linespec into explicit
	location.
	Move string representation of location to explicit_location_to_linespec
	and use it and explicit_location_to_string to save string
	representations of the canonical location.
	(create_sals_line_offset, convert_linespec_to_sals): `ls' contains an
	explicit location.  Update all references.
	(convert_explicit_location_to_sals): New function.
	(parse_linespec): Use PARSER_EXPLICIT to access the parser
	result's explicit location.
	(linespec_state_constructor): Initialize is_linespec.
	Use PARSER_EXPLICIT.
	(linespec_parser_delete): Use PARSER_EXPLICIT to access the parser's
	result.
	(event_location_to_sals): For linespec locations, set is_linespec.
	Handle explicit locations.
	(decode_objc): 'ls' contains an explicit location now. Update all
	references.
	(symtabs_from_filename): Use source_file_not_found_error.
	* location.c (struct event_location.u) <explicit>: New member.
	(initialize_explicit_location): New function.
	(initialize_event_location): Initialize explicit locations.
	(new_explicit_location, get_explicit_location)
	(get_explicit_location_const): New functions.
	(explicit_to_string_internal): New function; most of contents moved
	from canonicalize_linespec.
	(explicit_location_to_string): New function.
	(explicit_location_to_linespec): New function.
	(copy_event_location, delete_event_location)
	(event_location_to_string_const, event_location_empty_p): Handle
	explicit locations.
	* location.h (enum offset_relative_sign, struct line_offset): Move
	here from linespec.h.
	(enum event_location_type): Add EXPLICIT_LOCATION.
	(struct explicit_location): New structure.
	(explicit_location_to_string): Declare.
	(explicit_location_to_linespec): Declare.
	(new_explicit_location, get_explicit_locationp
	(get_explicit_location_const, initialize_explicit_location): Declare.
This commit is contained in:
Keith Seitz 2015-08-11 17:09:35 -07:00
parent 5b56227bdc
commit 00e52e5376
6 changed files with 523 additions and 159 deletions

View file

@ -50,6 +50,10 @@ struct event_location
/* An address in the inferior. */
CORE_ADDR address;
#define EL_ADDRESS(PTR) (PTR)->u.address
/* An explicit location. */
struct explicit_location explicit;
#define EL_EXPLICIT(PTR) (&((PTR)->u.explicit))
} u;
/* Cached string representation of this location. This is used, e.g., to
@ -68,6 +72,15 @@ event_location_type (const struct event_location *location)
/* See description in location.h. */
void
initialize_explicit_location (struct explicit_location *explicit)
{
memset (explicit, 0, sizeof (struct explicit_location));
explicit->line_offset.sign = LINE_OFFSET_UNKNOWN;
}
/* See description in location.h. */
struct event_location *
new_linespec_location (char **linespec)
{
@ -144,6 +157,137 @@ get_probe_location (const struct event_location *location)
/* See description in location.h. */
struct event_location *
new_explicit_location (const struct explicit_location *explicit)
{
struct event_location tmp;
memset (&tmp, 0, sizeof (struct event_location));
EL_TYPE (&tmp) = EXPLICIT_LOCATION;
initialize_explicit_location (EL_EXPLICIT (&tmp));
if (explicit != NULL)
{
if (explicit->source_filename != NULL)
{
EL_EXPLICIT (&tmp)->source_filename
= explicit->source_filename;
}
if (explicit->function_name != NULL)
EL_EXPLICIT (&tmp)->function_name
= explicit->function_name;
if (explicit->label_name != NULL)
EL_EXPLICIT (&tmp)->label_name = explicit->label_name;
if (explicit->line_offset.sign != LINE_OFFSET_UNKNOWN)
EL_EXPLICIT (&tmp)->line_offset = explicit->line_offset;
}
return copy_event_location (&tmp);
}
/* See description in location.h. */
struct explicit_location *
get_explicit_location (struct event_location *location)
{
gdb_assert (EL_TYPE (location) == EXPLICIT_LOCATION);
return EL_EXPLICIT (location);
}
/* See description in location.h. */
const struct explicit_location *
get_explicit_location_const (const struct event_location *location)
{
gdb_assert (EL_TYPE (location) == EXPLICIT_LOCATION);
return EL_EXPLICIT (location);
}
/* This convenience function returns a malloc'd string which
represents the location in EXPLICIT.
AS_LINESPEC is non-zero if this string should be a linespec.
Otherwise it will be output in explicit form. */
static char *
explicit_to_string_internal (int as_linespec,
const struct explicit_location *explicit)
{
struct ui_file *buf;
char space, *result;
int need_space = 0;
struct cleanup *cleanup;
space = as_linespec ? ':' : ' ';
buf = mem_fileopen ();
cleanup = make_cleanup_ui_file_delete (buf);
if (explicit->source_filename != NULL)
{
if (!as_linespec)
fputs_unfiltered ("-source ", buf);
fputs_unfiltered (explicit->source_filename, buf);
need_space = 1;
}
if (explicit->function_name != NULL)
{
if (need_space)
fputc_unfiltered (space, buf);
if (!as_linespec)
fputs_unfiltered ("-function ", buf);
fputs_unfiltered (explicit->function_name, buf);
need_space = 1;
}
if (explicit->label_name != NULL)
{
if (need_space)
fputc_unfiltered (space, buf);
if (!as_linespec)
fputs_unfiltered ("-label ", buf);
fputs_unfiltered (explicit->label_name, buf);
need_space = 1;
}
if (explicit->line_offset.sign != LINE_OFFSET_UNKNOWN)
{
if (need_space)
fputc_unfiltered (space, buf);
if (!as_linespec)
fputs_unfiltered ("-line ", buf);
fprintf_filtered (buf, "%s%d",
(explicit->line_offset.sign == LINE_OFFSET_NONE ? ""
: (explicit->line_offset.sign
== LINE_OFFSET_PLUS ? "+" : "-")),
explicit->line_offset.offset);
}
result = ui_file_xstrdup (buf, NULL);
do_cleanups (cleanup);
return result;
}
/* See description in location.h. */
char *
explicit_location_to_string (const struct explicit_location *explicit)
{
return explicit_to_string_internal (0, explicit);
}
/* See description in location.h. */
char *
explicit_location_to_linespec (const struct explicit_location *explicit)
{
return explicit_to_string_internal (1, explicit);
}
/* See description in location.h. */
struct event_location *
copy_event_location (const struct event_location *src)
{
@ -165,6 +309,22 @@ copy_event_location (const struct event_location *src)
EL_ADDRESS (dst) = EL_ADDRESS (src);
break;
case EXPLICIT_LOCATION:
if (EL_EXPLICIT (src)->source_filename != NULL)
EL_EXPLICIT (dst)->source_filename
= xstrdup (EL_EXPLICIT (src)->source_filename);
if (EL_EXPLICIT (src)->function_name != NULL)
EL_EXPLICIT (dst)->function_name
= xstrdup (EL_EXPLICIT (src)->function_name);
if (EL_EXPLICIT (src)->label_name != NULL)
EL_EXPLICIT (dst)->label_name = xstrdup (EL_EXPLICIT (src)->label_name);
EL_EXPLICIT (dst)->line_offset = EL_EXPLICIT (src)->line_offset;
break;
case PROBE_LOCATION:
if (EL_PROBE (src) != NULL)
EL_PROBE (dst) = xstrdup (EL_PROBE (src));
@ -214,6 +374,12 @@ delete_event_location (struct event_location *location)
/* Nothing to do. */
break;
case EXPLICIT_LOCATION:
xfree (EL_EXPLICIT (location)->source_filename);
xfree (EL_EXPLICIT (location)->function_name);
xfree (EL_EXPLICIT (location)->label_name);
break;
case PROBE_LOCATION:
xfree (EL_PROBE (location));
break;
@ -246,6 +412,11 @@ event_location_to_string (struct event_location *location)
core_addr_to_string (EL_ADDRESS (location)));
break;
case EXPLICIT_LOCATION:
EL_STRING (location)
= explicit_location_to_string (EL_EXPLICIT (location));
break;
case PROBE_LOCATION:
EL_STRING (location) = xstrdup (EL_PROBE (location));
break;
@ -312,6 +483,14 @@ event_location_empty_p (const struct event_location *location)
case ADDRESS_LOCATION:
return 0;
case EXPLICIT_LOCATION:
return (EL_EXPLICIT (location) == NULL
|| (EL_EXPLICIT (location)->source_filename == NULL
&& EL_EXPLICIT (location)->function_name == NULL
&& EL_EXPLICIT (location)->label_name == NULL
&& (EL_EXPLICIT (location)->line_offset.sign
== LINE_OFFSET_UNKNOWN)));
case PROBE_LOCATION:
return EL_PROBE (location) == NULL;