This is the mail archive of the
gdb-patches@sourceware.org
mailing list for the GDB project.
Re: [PATCH 17/40] Linespec lexing and C++ operators
- From: Keith Seitz <keiths at redhat dot com>
- To: Pedro Alves <palves at redhat dot com>, gdb-patches at sourceware dot org
- Date: Fri, 14 Jul 2017 14:45:47 -0700
- Subject: Re: [PATCH 17/40] Linespec lexing and C++ operators
- Authentication-results: sourceware.org; auth=none
- Authentication-results: ext-mx02.extmail.prod.ext.phx2.redhat.com; dmarc=none (p=none dis=none) header.from=redhat.com
- Authentication-results: ext-mx02.extmail.prod.ext.phx2.redhat.com; spf=pass smtp.mailfrom=keiths at redhat dot com
- Dkim-filter: OpenDKIM Filter v2.11.0 mx1.redhat.com 27955806BA
- Dmarc-filter: OpenDMARC Filter v1.3.2 mx1.redhat.com 27955806BA
- References: <1496406158-12663-1-git-send-email-palves@redhat.com> <1496406158-12663-18-git-send-email-palves@redhat.com>
On 06/02/2017 05:22 AM, Pedro Alves wrote:
> There's some lexing code in linespec that isn't handling C++ operators
> correctly. It's the usual confusion with operator< / operator<<, in
> code that wants to skip past template parameters.
>
> The linespec_lexer_lex_string change is necessary otherwise we get
> this (with current master):
>
> (gdb) break 'operator<'
> unmatched quote
>
> The need for the find_toplevel_char change was exposed by the use of
> that function in the explicit location completer. Without the fix,
> that completer is not able to "see" past operator< symbols, without
> quoting, like:
>
> (gdb) b -function operator<(int, int) -labe[TAB] # nothing happens
>
> gdb incorrectly thinks "-labe" is part of the "unclosed" template
> parameter list started with "<".
Ouch. The best laid plans...
Just a few trivial things.
> diff --git a/gdb/linespec.c b/gdb/linespec.c
> index 0216bf1..f24cca2 100644
> --- a/gdb/linespec.c
> +++ b/gdb/linespec.c
> @@ -674,14 +674,49 @@ linespec_lexer_lex_string (linespec_parser *parser)
> else if (*PARSER_STREAM (parser) == '<'
> || *PARSER_STREAM (parser) == '(')
> {
> - const char *p;
> + /* Don't interpret 'operator<' / 'operator<<' as a
> + template parameter list though. */
> + if (*PARSER_STREAM (parser) == '<'
> + && (PARSER_STATE (parser)->language->la_language
> + == language_cplus)
> + && (PARSER_STREAM (parser) - start) >= CP_OPERATOR_LEN)
> + {
> + const char *p = PARSER_STREAM (parser);
> +
> + while (p > start && isspace (p[-1]))
> + p--;
> + if (p - start >= CP_OPERATOR_LEN)
> + {
> + p-= CP_OPERATOR_LEN;
This is a cut-n-paste-o (that's a typo propagated via cut-n-paste). Missing a space before the operator.
> + if (strncmp (p, CP_OPERATOR_STR, CP_OPERATOR_LEN) == 0
> + && (p == start
> + || !(isalnum (p[-1]) || p[-1] == '_')))
> + {
> + /* This is an operator name. Keep going. */
> + ++(PARSER_STREAM (parser));
> + if (*PARSER_STREAM (parser) == '<')
> + ++(PARSER_STREAM (parser));
> + continue;
> + }
> + }
> + }
>
> - p = find_parameter_list_end (PARSER_STREAM (parser));
> - if (p != NULL)
> + const char *p = find_parameter_list_end (PARSER_STREAM (parser));
> + PARSER_STREAM (parser) = p;
> +
> + /* Don't loop around to the normal \0 case above because
> + we don't want to misinterpret a potential keyword at
> + the end of the token when the string isn't
> + "()<>"-balanced. This handles "b
> + function(thread<tab>" in completion mode. */
> + if (*p == '\0')
> {
> - PARSER_STREAM (parser) = p;
> - continue;
> + LS_TOKEN_STOKEN (token).ptr = start;
> + LS_TOKEN_STOKEN (token).length = PARSER_STREAM (parser) - start;
Line length > 80?
> + return token;
> }
> + else
> + continue;
> }
> /* Commas are terminators, but not if they are part of an
> operator name. */
Keith