Re: [PATCH 32/40] Make "break foo" find "A::foo", A::B::foo", etc. [C++ and wild matching]

Pedro Alves
2017-11-24T16:48:35Z

Hey Keith,

So I took your suggestion and ran with it. And in the end
I like it! See more below.

On 11/22/2017 04:48 PM, Pedro Alves wrote:

>
> On 08/09/2017 12:48 AM, Keith Seitz wrote:
>> On 06/02/2017 05:22 AM, Pedro Alves wrote:
>>

>>> /* This help string is used for the break, hbreak, tbreak and thbreak
>>> commands. It is defined as a macro to prevent duplication.
>>> diff --git a/gdb/completer.c b/gdb/completer.c
>>> index eabbce7..99e40a3 100644
>>> --- a/gdb/completer.c
>>> +++ b/gdb/completer.c
>>> @@ -609,6 +612,7 @@ static const char *const explicit_options[] =
>>> {
>>> "-source",
>>> "-function",
>>> + "-qualified",
>>> "-line",
>>> "-label",
>>> NULL
>>
>> The "-qualified" option can be used with linespecs, too, right?
>
> Not really, no.
>
>>
>> (gdb) b -qualified A::b (a linespec location)
>> (gdb) b -qualified -function A::b (an explicit location)
>>
>> Actually, I see that it does not work (yet?). Consider:
>>
>> 1 struct A
>> 2 {
>> 3 int doit ()
>> 4 {
>> 5 int i;
>> 6
>> 7 for (i = 0; i < 10; ++i)
>> 8 {
>> 9 switch (i)
>> 10 {
>> 11 top:
>> 12 case 5:
>> 13 ++i;
>> 14 goto top;
>> 15 default: break;
>> 16 }
>> 17 }
>> 18 return i;
>> 19 }
>> 20 };
>>
>> (gdb) b A::doit:top
>> Breakpoint 1 at 0x400633: file simple-label.cc, line 11.
>> (gdb) b -function A::doit -label top
>> Note: breakpoint 1 also set at pc 0x400633.
>> Breakpoint 2 at 0x400633: file simple-label.cc, line 11.
>> (gdb) b -qualified A::doit:top
>> Function "A::doit:top" not defined.
>> Make breakpoint pending on future shared library load? (y or [n]) n
>> (gdb) b -qualified A::doit -label top
>> Note: breakpoints 1 and 2 also set at pc 0x400633.
>> Breakpoint 3 at 0x400633: file simple-label.cc, line 11.
>>
>> Is there a reason to exclude linespecs? Perhaps naively, I would have thought to
>> make -qualified a parsing option instead of a replacement for -function.
>
> I went this route because it seemed to me that a separate
> option would end up being less convenient, because it forces you
> to type/combine two options:
>
> (gdb) b -q -f A::doit:top
>

Sorry, here I was really trying to talk about:

(gdb) b -q -f A::doit -label top

vs:

(gdb) b -q A::doit -label top

But ...

> and I thought that since you're requiring an option, and
> explicit linespecs are just superior to regular linespecs, that
> it'd be OK to move users to explicit linespecs if they need
> a qualified name.
>

> Dunno.

... well, I'll be d*mn+d... I gave your suggestion a try, and
I actually like it! If we make "-qualified" a flag instead of an
option with an argument, then usual case of:

(gdb) b -q A::doit

works the exact same. It's only when you specify source files
and labels that it makes a difference. So with your suggestion,
we get a lot of benefit (works with linespecs, which is the common
case, I guess) with only a mild downside (a little more typing in
the explicit location case).

Here's what the delta patch looks like. I left "-qualified"
as an explicit location option, rather than splitting the parsing
of "qualified" and the real explicit options, because this way
support for "-qualified" in the middle of other options
"-source filename.cc -qualified -function func" falls out
naturally.

Surprisingly, I didn't have to change much in the tests. But I did
extend them to cover these new possibilities. I'll show the tests
delta as a follow up.

From b84d26c68ced2a6544660e1f3cf5584c9e1dd4ef Mon Sep 17 00:00:00 2001
From: Pedro Alves <palves@redhat.com>
Date: Fri, 24 Nov 2017 15:28:43 +0000
Subject: [PATCH] alternative

---
gdb/ax-gdb.c | 3 +-
gdb/breakpoint.c | 23 +++++++------
gdb/completer.c | 39 +++++++++++++++++----
gdb/guile/scm-breakpoint.c | 6 ++--
gdb/linespec.c | 31 +++++++++++------
gdb/linespec.h | 3 +-
gdb/location.c | 86 ++++++++++++++++++++++++++++++----------------
gdb/location.h | 35 ++++++++++++++-----
gdb/mi/mi-cmd-break.c | 3 +-
gdb/python/py-breakpoint.c | 3 +-
gdb/python/python.c | 3 +-
11 files changed, 163 insertions(+), 72 deletions(-)

diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index 52ca081..5027f6a 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -2638,7 +2638,8 @@ agent_command_1 (const char *exp, int eval)

exp = skip_spaces (exp);

- event_location_up location = new_linespec_location (&exp);
+ event_location_up location
+ = new_linespec_location (&exp, symbol_name_match_type::WILD);
decode_line_full (location.get (), DECODE_LINE_FUNFIRSTLINE, NULL,
(struct symtab *) NULL, 0, &canonical,
NULL, NULL);
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 88cb505..c7bb77d 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -9100,9 +9100,9 @@ parse_breakpoint_sals (const struct event_location *location,

if (event_location_type (location) == LINESPEC_LOCATION)
{
- const char *address = get_linespec_location (location);
+ const char *spec = get_linespec_location (location)->spec_string;

- if (address == NULL)
+ if (spec == NULL)
{
/* The last displayed codepoint, if it's valid, is our default
breakpoint address. */
@@ -9148,15 +9148,15 @@ parse_breakpoint_sals (const struct event_location *location,
cursal = get_current_source_symtab_and_line ();
if (last_displayed_sal_is_valid ())
{
- const char *address = NULL;
+ const char *spec = NULL;

if (event_location_type (location) == LINESPEC_LOCATION)
- address = get_linespec_location (location);
+ spec = get_linespec_location (location)->spec_string;

if (!cursal.symtab
- || (address != NULL
- && strchr ("+-", address[0]) != NULL
- && address[1] != '['))
+ || (spec != NULL
+ && strchr ("+-", spec[0]) != NULL
+ && spec[1] != '['))
{
decode_line_full (location, DECODE_LINE_FUNFIRSTLINE, NULL,
get_last_displayed_symtab (),
@@ -13147,12 +13147,13 @@ strace_marker_create_sals_from_location (const struct event_location *location,
struct linespec_sals lsal;
const char *arg_start, *arg;

- arg = arg_start = get_linespec_location (location);
+ arg = arg_start = get_linespec_location (location)->spec_string;
lsal.sals = decode_static_tracepoint_spec (&arg);

std::string str (arg_start, arg - arg_start);
const char *ptr = str.c_str ();
- canonical->location = new_linespec_location (&ptr);
+ canonical->location
+ = new_linespec_location (&ptr, symbol_name_match_type::FULL);

lsal.canonical
= xstrdup (event_location_to_string (canonical->location.get ()));
@@ -13213,7 +13214,7 @@ strace_marker_decode_location (struct breakpoint *b,
struct program_space *search_pspace)
{
struct tracepoint *tp = (struct tracepoint *) b;
- const char *s = get_linespec_location (location);
+ const char *s = get_linespec_location (location)->spec_string;

std::vector<symtab_and_line> sals = decode_static_tracepoint_spec (&s);
if (sals.size () > tp->static_trace_marker_id_idx)
@@ -14759,7 +14760,7 @@ strace_command (const char *arg, int from_tty)
if (arg && startswith (arg, "-m") && isspace (arg[2]))
{
ops = &strace_marker_breakpoint_ops;
- location = new_linespec_location (&arg);
+ location = new_linespec_location (&arg, symbol_name_match_type::FULL);
}
else
{
diff --git a/gdb/completer.c b/gdb/completer.c
index aa0f105..d0224aa 100644
--- a/gdb/completer.c
+++ b/gdb/completer.c
@@ -582,7 +582,8 @@ complete_source_filenames (const char *text)

static void
complete_address_and_linespec_locations (completion_tracker &tracker,
- const char *text)
+ const char *text,
+ symbol_name_match_type match_type)
{
if (*text == '*')
{
@@ -594,7 +595,7 @@ complete_address_and_linespec_locations (completion_tracker &tracker,
}
else
{
- linespec_complete (tracker, text);
+ linespec_complete (tracker, text, match_type);
}
}

@@ -642,6 +643,9 @@ collect_explicit_location_matches (completion_tracker &tracker,
const struct explicit_location *explicit_loc
= get_explicit_location (location);

+ /* True if the option expects an argument. */
+ bool needs_arg = true;
+
/* Note, in the various MATCH_* below, we complete on
explicit_loc->foo instead of WORD, because only the former will
have already skipped past any quote char. */
@@ -657,7 +661,6 @@ collect_explicit_location_matches (completion_tracker &tracker,
break;

case MATCH_FUNCTION:
- case MATCH_QUALIFIED:
{
const char *function = string_or_empty (explicit_loc->function_name);
linespec_complete_function (tracker, function,
@@ -666,6 +669,9 @@ collect_explicit_location_matches (completion_tracker &tracker,
}
break;

+ case MATCH_QUALIFIED:
+ needs_arg = false;
+ break;
case MATCH_LINE:
/* Nothing to offer. */
break;
@@ -685,7 +691,7 @@ collect_explicit_location_matches (completion_tracker &tracker,
gdb_assert_not_reached ("unhandled explicit_location_match_type");
}

- if (tracker.completes_to_completion_word (word))
+ if (!needs_arg || tracker.completes_to_completion_word (word))
{
tracker.discard_completions ();
tracker.advance_custom_word_point_by (strlen (word));
@@ -874,7 +880,7 @@ location_completer (struct cmd_list_element *ignore,
tracker.advance_custom_word_point_by (1);
}

- if (location != NULL)
+ if (completion_info.saw_explicit_location_option)
{
if (*copy != '\0')
{
@@ -914,10 +920,29 @@ location_completer (struct cmd_list_element *ignore,

}
}
+ /* This is an address or linespec location. */
+ else if (location != NULL)
+ {
+ /* Handle non-explicit location options. */
+
+ int keyword = skip_keyword (tracker, explicit_options, &text);
+ if (keyword == -1)
+ complete_on_enum (tracker, explicit_options, text, text);
+ else
+ {
+ tracker.advance_custom_word_point_by (copy - text);
+ text = copy;
+
+ symbol_name_match_type match_type
+ = get_explicit_location (location.get ())->func_name_match_type;
+ complete_address_and_linespec_locations (tracker, text, match_type);
+ }
+ }
else
{
- /* This is an address or linespec location. */
- complete_address_and_linespec_locations (tracker, text);
+ /* No options. */
+ complete_address_and_linespec_locations (tracker, text,
+ symbol_name_match_type::WILD);
}

/* Add matches for option names, if either:
diff --git a/gdb/guile/scm-breakpoint.c b/gdb/guile/scm-breakpoint.c
index ec75be5..f84815e 100644
--- a/gdb/guile/scm-breakpoint.c
+++ b/gdb/guile/scm-breakpoint.c
@@ -424,8 +424,10 @@ gdbscm_register_breakpoint_x (SCM self)
pending_breakpoint_scm = self;
location = bp_smob->spec.location;
copy = skip_spaces (location);
- event_location_up eloc = string_to_event_location_basic (&copy,
- current_language);
+ event_location_up eloc
+ = string_to_event_location_basic (&copy,
+ current_language,
+ symbol_name_match_type::WILD);

TRY
{
diff --git a/gdb/linespec.c b/gdb/linespec.c
index c11ca1d..fca3efd 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -302,6 +302,9 @@ struct ls_parser
struct linespec result;
#define PARSER_RESULT(PPTR) (&(PPTR)->result)

+ /* Whether to do full matching or wild matching. */
+ symbol_name_match_type match_type;
+
/* What the parser believes the current word point should complete
to. */
linespec_complete_what complete_what;
@@ -1869,7 +1872,7 @@ linespec_parse_basic (linespec_parser *parser)

linespec_complete_function (tmp_tracker,
parser->completion_word,
- symbol_name_match_type::WILD,
+ parser->match_type,
source_filename);

if (tmp_tracker.have_completions ())
@@ -1894,7 +1897,7 @@ linespec_parse_basic (linespec_parser *parser)
/* Try looking it up as a function/method. */
find_linespec_symbols (PARSER_STATE (parser),
PARSER_RESULT (parser)->file_symtabs, name,
- symbol_name_match_type::WILD,
+ parser->match_type,
&symbols, &minimal_symbols);

if (symbols != NULL || minimal_symbols != NULL)
@@ -2511,10 +2514,12 @@ convert_explicit_location_to_sals (struct linespec_state *self,
if no file is validly specified. Callers must check that.
Also, the line number returned may be invalid. */

-/* Parse the linespec in ARG. */
+/* Parse the linespec in ARG. MATCH_TYPE indicates how function names
+ should be matched. */

static std::vector<symtab_and_line>
-parse_linespec (linespec_parser *parser, const char *arg)
+parse_linespec (linespec_parser *parser, const char *arg,
+ symbol_name_match_type match_type)
{
linespec_token token;
struct gdb_exception file_exception = exception_none;
@@ -2544,6 +2549,7 @@ parse_linespec (linespec_parser *parser, const char *arg)
parser->lexer.stream = arg;
parser->completion_word = arg;
parser->complete_what = linespec_complete_what::FUNCTION;
+ parser->match_type = match_type;

/* Initialize the default symtab and line offset. */
initialize_defaults (&PARSER_STATE (parser)->default_symtab,
@@ -2875,7 +2881,7 @@ complete_linespec_component (linespec_parser *parser,
{
completion_list fn_list;

- linespec_complete_function (tracker, text, symbol_name_match_type::WILD,
+ linespec_complete_function (tracker, text, parser->match_type,
source_filename);
if (source_filename == NULL)
{
@@ -2981,7 +2987,8 @@ linespec_complete_label (completion_tracker &tracker,
/* See description in linespec.h. */

void
-linespec_complete (completion_tracker &tracker, const char *text)
+linespec_complete (completion_tracker &tracker, const char *text,
+ symbol_name_match_type match_type)
{
linespec_parser parser;
struct cleanup *cleanup;
@@ -2990,6 +2997,7 @@ linespec_complete (completion_tracker &tracker, const char *text)
linespec_parser_new (&parser, 0, current_language, NULL, NULL, 0, NULL);
cleanup = make_cleanup (linespec_parser_delete, &parser);
parser.lexer.saved_arg = text;
+ parser.match_type = match_type;
PARSER_STREAM (&parser) = text;

parser.completion_tracker = &tracker;
@@ -2999,7 +3007,7 @@ linespec_complete (completion_tracker &tracker, const char *text)
furthest completion point we managed to parse to. */
TRY
{
- parse_linespec (&parser, text);
+ parse_linespec (&parser, text, match_type);
}
CATCH (except, RETURN_MASK_ERROR)
{
@@ -3047,7 +3055,7 @@ linespec_complete (completion_tracker &tracker, const char *text)
VEC (bound_minimal_symbol_d) *minimal_symbols;
find_linespec_symbols (PARSER_STATE (&parser),
PARSER_RESULT (&parser)->file_symtabs,
- func_name, symbol_name_match_type::WILD,
+ func_name, parser.match_type,
&function_symbols, &minimal_symbols);

PARSER_RESULT (&parser)->function_symbols = function_symbols;
@@ -3189,7 +3197,9 @@ event_location_to_sals (linespec_parser *parser,
PARSER_STATE (parser)->is_linespec = 1;
TRY
{
- result = parse_linespec (parser, get_linespec_location (location));
+ const linespec_location *ls = get_linespec_location (location);
+ result = parse_linespec (parser,
+ ls->spec_string, ls->match_type);
}
CATCH (except, RETURN_MASK_ERROR)
{
@@ -3500,7 +3510,8 @@ decode_objc (struct linespec_state *self, linespec_p ls, const char *arg)
else
str = saved_arg;

- self->canonical->location = new_linespec_location (&str);
+ self->canonical->location
+ = new_linespec_location (&str, symbol_name_match_type::FULL);
}
}

diff --git a/gdb/linespec.h b/gdb/linespec.h
index 7add83e..85beb62 100644
--- a/gdb/linespec.h
+++ b/gdb/linespec.h
@@ -180,7 +180,8 @@ extern const char * const linespec_keywords[];
/* Complete a linespec. */

extern void linespec_complete (completion_tracker &tracker,
- const char *text);
+ const char *text,
+ symbol_name_match_type match_type);

/* Complete a function symbol, in linespec mode, according to
FUNC_MATCH_TYPE. If SOURCE_FILENAME is non-NULL, limits completion
diff --git a/gdb/location.c b/gdb/location.c
index cbd37ba..c767890 100644
--- a/gdb/location.c
+++ b/gdb/location.c
@@ -41,13 +41,14 @@ struct event_location

union
{
- /* A generic "this is a string specification" for a location.
- This representation is used by both "normal" linespecs and
- probes. */
+ /* A probe. */
char *addr_string;
-#define EL_LINESPEC(P) ((P)->u.addr_string)
#define EL_PROBE(P) ((P)->u.addr_string)

+ /* A "normal" linespec. */
+ struct linespec_location linespec_location;
+#define EL_LINESPEC(P) (&(P)->u.linespec_location)
+
/* An address in the inferior. */
CORE_ADDR address;
#define EL_ADDRESS(P) (P)->u.address
@@ -78,17 +79,20 @@ initialize_explicit_location (struct explicit_location *explicit_loc)
{
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;
}

/* See description in location.h. */

event_location_up
-new_linespec_location (const char **linespec)
+new_linespec_location (const char **linespec,
+ symbol_name_match_type match_type)
{
struct event_location *location;

location = XCNEW (struct event_location);
EL_TYPE (location) = LINESPEC_LOCATION;
+ EL_LINESPEC (location)->match_type = match_type;
if (*linespec != NULL)
{
const char *p;
@@ -97,14 +101,14 @@ new_linespec_location (const char **linespec)
linespec_lex_to_end (linespec);
p = remove_trailing_whitespace (orig, *linespec);
if ((p - orig) > 0)
- EL_LINESPEC (location) = savestring (orig, p - orig);
+ EL_LINESPEC (location)->spec_string = savestring (orig, p - orig);
}
return event_location_up (location);
}

/* See description in location.h. */

-const char *
+const linespec_location *
get_linespec_location (const struct event_location *location)
{
gdb_assert (EL_TYPE (location) == LINESPEC_LOCATION);
@@ -249,8 +253,7 @@ explicit_to_string_internal (int as_linespec,
if (explicit_loc->func_name_match_type
== symbol_name_match_type::FULL)
buf.puts ("-qualified ");
- else
- buf.puts ("-function ");
+ buf.puts ("-function ");
}
buf.puts (explicit_loc->function_name);
need_space = 1;
@@ -313,8 +316,10 @@ copy_event_location (const struct event_location *src)
switch (EL_TYPE (src))
{
case LINESPEC_LOCATION:
- if (EL_LINESPEC (src) != NULL)
- EL_LINESPEC (dst) = xstrdup (EL_LINESPEC (src));
+ EL_LINESPEC (dst)->match_type = EL_LINESPEC (src)->match_type;
+ if (EL_LINESPEC (src)->spec_string != NULL)
+ EL_LINESPEC (dst)->spec_string
+ = xstrdup (EL_LINESPEC (src)->spec_string);
break;

case ADDRESS_LOCATION:
@@ -359,7 +364,7 @@ event_location_deleter::operator() (event_location *location) const
switch (EL_TYPE (location))
{
case LINESPEC_LOCATION:
- xfree (EL_LINESPEC (location));
+ xfree (EL_LINESPEC (location)->spec_string);
break;

case ADDRESS_LOCATION:
@@ -394,8 +399,17 @@ event_location_to_string (struct event_location *location)
switch (EL_TYPE (location))
{
case LINESPEC_LOCATION:
- if (EL_LINESPEC (location) != NULL)
- EL_STRING (location) = xstrdup (EL_LINESPEC (location));
+ if (EL_LINESPEC (location)->spec_string != NULL)
+ {
+ linespec_location *ls = EL_LINESPEC (location);
+ if (ls->match_type == symbol_name_match_type::FULL)
+ {
+ EL_STRING (location)
+ = concat ("-qualified ", ls->spec_string, (char *) NULL);
+ }
+ else
+ EL_STRING (location) = xstrdup (ls->spec_string);
+ }
break;

case ADDRESS_LOCATION:
@@ -762,12 +776,23 @@ string_to_explicit_location (const char **argp,
argument. */
bool have_oarg = false;

+ /* True if the option needs an argument. */
+ bool need_oarg = false;
+
/* Convenience to consistently set both OARG/HAVE_OARG from
ARG. */
auto set_oarg = [&] (gdb::unique_xmalloc_ptr<char> arg)
{
+ if (completion_info != NULL)
+ {
+ /* We do this here because the set of options that take
+ arguments matches the set of explicit location
+ options. */
+ completion_info->saw_explicit_location_option = true;
+ }
oarg = std::move (arg);
have_oarg = oarg != NULL;
+ need_oarg = true;
};

if (strncmp (opt.get (), "-source", len) == 0)
@@ -781,14 +806,9 @@ string_to_explicit_location (const char **argp,
set_oarg (explicit_location_lex_one_function (argp, language,
completion_info));
EL_EXPLICIT (location)->function_name = oarg.release ();
- EL_EXPLICIT (location)->func_name_match_type
- = symbol_name_match_type::WILD;
}
else if (strncmp (opt.get (), "-qualified", len) == 0)
{
- set_oarg (explicit_location_lex_one_function (argp, language,
- completion_info));
- EL_EXPLICIT (location)->function_name = oarg.release ();
EL_EXPLICIT (location)->func_name_match_type
= symbol_name_match_type::FULL;
}
@@ -830,7 +850,7 @@ string_to_explicit_location (const char **argp,
case, it provides a much better user experience to issue
the "invalid argument" error before any missing
argument error. */
- if (!have_oarg && completion_info == NULL)
+ if (need_oarg && !have_oarg && completion_info == NULL)
error (_("missing argument for \"%s\""), opt.get ());
}

@@ -853,7 +873,8 @@ string_to_explicit_location (const char **argp,

event_location_up
string_to_event_location_basic (const char **stringp,
- const struct language_defn *language)
+ const struct language_defn *language,
+ symbol_name_match_type match_type)
{
event_location_up location;
const char *cs;
@@ -881,7 +902,7 @@ string_to_event_location_basic (const char **stringp,
else
{
/* Everything else is a linespec. */
- location = new_linespec_location (stringp);
+ location = new_linespec_location (stringp, match_type);
}
}

@@ -895,6 +916,7 @@ string_to_event_location (const char **stringp,
const struct language_defn *language)
{
const char *arg, *orig;
+ symbol_name_match_type match_type = symbol_name_match_type::WILD;

/* Try an explicit location. */
orig = arg = *stringp;
@@ -904,15 +926,21 @@ string_to_event_location (const char **stringp,
/* It was a valid explicit location. Advance STRINGP to
the end of input. */
*stringp += arg - orig;
- }
- else
- {
- /* Everything else is a "basic" linespec, address, or probe
- location. */
- location = string_to_event_location_basic (stringp, language);
+
+ /* If the user really specified a location, then we're done. */
+ if (!event_location_empty_p (location.get ()))
+ return location;
+
+ /* Otherwise, the user _only_ specified optional flags like
+ "-qualified", otherwise string_to_explicit_location would
+ have thrown an error. Save the flags for "basic" linespec
+ parsing below and discard the explicit location. */
+ match_type = EL_EXPLICIT (location)->func_name_match_type;
}

- return location;
+ /* Everything else is a "basic" linespec, address, or probe
+ location. */
+ return string_to_event_location_basic (stringp, language, match_type);
}

/* See description in location.h. */
diff --git a/gdb/location.h b/gdb/location.h
index 74fd868..fcfa8fb 100644
--- a/gdb/location.h
+++ b/gdb/location.h
@@ -66,6 +66,17 @@ enum event_location_type
PROBE_LOCATION
};

+/* A traditional linespec. */
+
+struct linespec_location
+{
+ /* Whether the function name is fully-qualified or not. */
+ symbol_name_match_type match_type;
+
+ /* The linespec. */
+ char *spec_string;
+};
+
/* An explicit location. This structure is used to bypass the
parsing done on linespecs. It still has the same requirements
as linespecs, though. For example, source_filename requires
@@ -110,7 +121,7 @@ extern char *

/* Return a string representation of the LOCATION.
This function may return NULL for unspecified linespecs,
- e.g, LOCATION_LINESPEC and addr_string is NULL.
+ e.g, LINESPEC_LOCATION and spec_string is NULL.

The result is cached in LOCATION. */

@@ -130,12 +141,13 @@ typedef std::unique_ptr<event_location, event_location_deleter>

/* Create a new linespec location. */

-extern event_location_up new_linespec_location (const char **linespec);
+extern event_location_up new_linespec_location
+ (const char **linespec, symbol_name_match_type match_type);

-/* Return the linespec location (a string) of the given event_location
- (which must be of type LINESPEC_LOCATION). */
+/* Return the linespec location of the given event_location (which
+ must be of type LINESPEC_LOCATION). */

-extern const char *
+extern const linespec_location *
get_linespec_location (const struct event_location *location);

/* Create a new address location.
@@ -214,12 +226,14 @@ extern event_location_up
string_to_event_location (const char **argp,
const struct language_defn *langauge);

-/* Like string_to_event_location, but does not attempt to parse explicit
- locations. */
+/* Like string_to_event_location, but does not attempt to parse
+ explicit locations. MATCH_TYPE indicates how function names should
+ be matched. */

extern event_location_up
string_to_event_location_basic (const char **argp,
- const struct language_defn *language);
+ const struct language_defn *language,
+ symbol_name_match_type match_type);

/* Structure filled in by string_to_explicit_location to aid the
completer. */
@@ -236,6 +250,11 @@ struct explicit_completion_info
If the last option is not quoted, then both are set to NULL. */
const char *quoted_arg_start = NULL;
const char *quoted_arg_end = NULL;
+
+ /* True if we saw an explicit location option, as opposed to only
+ flags that affect both explicit locations and linespecs, like
+ "-qualified". */
+ bool saw_explicit_location_option = false;
};

/* Attempt to convert the input string in *ARGP into an explicit location.
diff --git a/gdb/mi/mi-cmd-break.c b/gdb/mi/mi-cmd-break.c
index 833bdc0..6cb1d71 100644
--- a/gdb/mi/mi-cmd-break.c
+++ b/gdb/mi/mi-cmd-break.c
@@ -337,7 +337,8 @@ mi_cmd_break_insert_1 (int dprintf, const char *command, char **argv, int argc)
}
else
{
- location = string_to_event_location_basic (&address, current_language);
+ location = string_to_event_location_basic (&address, current_language,
+ symbol_name_match_type::WILD);
if (*address)
error (_("Garbage '%s' at end of location"), address);
}
diff --git a/gdb/python/py-breakpoint.c b/gdb/python/py-breakpoint.c
index 86719d1..5bc073e 100644
--- a/gdb/python/py-breakpoint.c
+++ b/gdb/python/py-breakpoint.c
@@ -681,7 +681,8 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
case bp_breakpoint:
{
event_location_up location
- = string_to_event_location_basic (&copy, current_language);
+ = string_to_event_location_basic (&copy, current_language,
+ symbol_name_match_type::WILD);
create_breakpoint (python_gdbarch,
location.get (), NULL, -1, NULL,
0,
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 5f15261..8ca2eed 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -838,7 +838,8 @@ gdbpy_decode_line (PyObject *self, PyObject *args)
return NULL;

if (arg != NULL)
- location = string_to_event_location_basic (&arg, python_language);
+ location = string_to_event_location_basic (&arg, python_language,
+ symbol_name_match_type::WILD);

std::vector<symtab_and_line> decoded_sals;
symtab_and_line def_sal;
--
2.5.5