@@ -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);
@@ -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
{
@@ -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:
@@ -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 (©,
- current_language);
+ event_location_up eloc
+ = string_to_event_location_basic (©,
+ current_language,
+ symbol_name_match_type::WILD);
TRY
{
@@ -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);
}
}
@@ -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
@@ -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. */
@@ -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.
@@ -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);
}
@@ -681,7 +681,8 @@ bppy_init (PyObject *self, PyObject *args, PyObject *kwargs)
case bp_breakpoint:
{
event_location_up location
- = string_to_event_location_basic (©, current_language);
+ = string_to_event_location_basic (©, current_language,
+ symbol_name_match_type::WILD);
create_breakpoint (python_gdbarch,
location.get (), NULL, -1, NULL,
0,
@@ -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;