[PATCH 2/6] Introduce `pre_expanded sals'

Sergio Durigan Junior
2011-04-04T03:08:31Z

Hi,

This patch introduces the `pre_expanded sals'. Tom, please, if you have
additional comments to make regarding this modification, feel free to
reply to this message.

This was regtested on the compile farm.

Thanks,

Sergio.

---
gdb/ChangeLog | 8 ++++++++
gdb/breakpoint.c | 52 ++++++++++++++++++++++++++++++++++++++++++++--------
gdb/linespec.h | 4 ++++
3 files changed, 56 insertions(+), 8 deletions(-)

diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index a5d2aa1..f20653b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,11 @@
+2011-04-04 Tom Tromey <tromey@redhat.com>
+
+ * breakpoint.c (create_breakpoints_sal): Added code to handle
+ pre-expanded sals.
+ (create_breakpoint): Likewise.
+ (breakpoint_re_set_one): Likewise.
+ * linespec.h (struct linespec_result) <pre_expanded>: New field.
+
2011-04-03 Joel Brobecker <brobecker@adacore.com>

GDB 7.3 branch created (branch timestamp: 2011-04-01 01:00 UTC)
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 2a25c8d..3927171 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -7629,6 +7629,16 @@ create_breakpoints_sal (struct gdbarch *gdbarch,
{
int i;

+ if (canonical->pre_expanded)
+ {
+ create_breakpoint_sal (gdbarch, sals, canonical->canonical[0],
+ cond_string, type, disposition,
+ thread, task, ignore_count, ops,
+ from_tty, enabled, internal,
+ canonical->special_display);
+ return;
+ }
+
for (i = 0; i < sals.nelts; ++i)
{
struct symtabs_and_lines expanded =
@@ -8154,7 +8164,7 @@ create_breakpoint (struct gdbarch *gdbarch,
mention (b);
}

- if (sals.nelts > 1)
+ if (sals.nelts > 1 && !canonical.pre_expanded)
{
warning (_("Multiple breakpoints were set.\nUse the "
"\"delete\" command to delete unwanted breakpoints."));
@@ -10952,12 +10962,14 @@ update_breakpoint_locations (struct breakpoint *b,
On return, FOUND will be 1 if any SaL was found, zero otherwise. */

static struct symtabs_and_lines
-addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
+addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found,
+ int *pre_expanded)
{
char *s;
int marker_spec, not_found;
struct symtabs_and_lines sals = {0};
struct gdb_exception e;
+ int my_pre_expanded = 0;

s = addr_string;
marker_spec = b->type == bp_static_tracepoint && is_marker_spec (s);
@@ -10976,8 +10988,27 @@ addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)
error (_("marker %s not found"), b->static_trace_marker_id);
}
else
- sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0,
- NULL, &not_found);
+ {
+ struct linespec_result canonical;
+
+ init_linespec_result (&canonical);
+ sals = decode_line_1 (&s, 1, (struct symtab *) NULL, 0,
+ &canonical, &not_found);
+
+ /* We don't need the contents. */
+ if (canonical.canonical)
+ {
+ int i;
+
+ for (i = 0; i < sals.nelts; ++i)
+ xfree (canonical.canonical[i]);
+ xfree (canonical.canonical);
+ }
+
+ my_pre_expanded = canonical.pre_expanded;
+ if (pre_expanded)
+ *pre_expanded = my_pre_expanded;
+ }
}
if (e.reason < 0)
{
@@ -11010,7 +11041,7 @@ addr_string_to_sals (struct breakpoint *b, char *addr_string, int *found)

if (!not_found)
{
- gdb_assert (sals.nelts == 1);
+ gdb_assert (my_pre_expanded || sals.nelts == 1);

resolve_sal_pc (&sals.sals[0]);
if (b->condition_not_parsed && s && s[0])
@@ -11049,22 +11080,27 @@ re_set_breakpoint (struct breakpoint *b)
struct symtabs_and_lines expanded = {0};
struct symtabs_and_lines expanded_end = {0};
struct cleanup *cleanups = make_cleanup (null_cleanup, NULL);
+ int pre_expanded = 0;

input_radix = b->input_radix;
save_current_space_and_thread ();
switch_to_program_space_and_thread (b->pspace);
set_language (b->language);

- sals = addr_string_to_sals (b, b->addr_string, &found);
+ sals = addr_string_to_sals (b, b->addr_string, &found, &pre_expanded);
if (found)
{
make_cleanup (xfree, sals.sals);
- expanded = expand_line_sal_maybe (sals.sals[0]);
+ if (pre_expanded)
+ expanded = sals;
+ else
+ expanded = expand_line_sal_maybe (sals.sals[0]);
}

if (b->addr_string_range_end)
{
- sals_end = addr_string_to_sals (b, b->addr_string_range_end, &found);
+ sals_end = addr_string_to_sals (b, b->addr_string_range_end, &found,
+ NULL);
if (found)
{
make_cleanup (xfree, sals_end.sals);
diff --git a/gdb/linespec.h b/gdb/linespec.h
index d8d2ec9..458235c 100644
--- a/gdb/linespec.h
+++ b/gdb/linespec.h
@@ -30,6 +30,10 @@ struct linespec_result
display mechanism would do the wrong thing. */
int special_display;

+ /* If non-zero, the linespec result should be considered to be a
+ "pre-expanded" multi-location linespec. */
+ int pre_expanded;
+
/* If non-NULL, an array of canonical names for returned
symtab_and_line objects. The array has as many elements as the
`nelts' field in the symtabs_and_line returned by decode_line_1.