Support template lookups in strncmp_iw_with_mode
This patch adds support for wild template parameter list matches, similar to how ABI tags or function overloads are now handled. With this patch, users will be able to "gloss over" the details of matching template parameter lists. This is accomplished by adding (yet more) logic to strncmp_iw_with_mode to skip parameter lists if none is explicitly given by the user. Here's a simple example using gdb.linespec/cpls-ops.exp: Before ------ (gdb) ptype test_op_call type = struct test_op_call { public: void operator()(void); void operator()(int); void operator()(long); void operator()<int>(int *); } (gdb) b test_op_call::operator() Breakpoint 1 at 0x400583: test_op_call::operator(). (3 locations) (gdb) i b Num Type Disp Enb Address What 1 breakpoint keep y <MULTIPLE> 1.1 y 0x400583 in test_op_call::operator()(int) at cpls-ops.cc:43 1.2 y 0x40058e in test_op_call::operator()() at cpls-ops.cc:47 1.3 y 0x40059e in test_op_call::operator()(long) at cpls-ops.cc:51 The breakpoint at test_op_call::operator()<int> was never set. After ----- (gdb) b test_op_call::operator() Breakpoint 1 at 0x400583: test_op_call::operator(). (4 locations) (gdb) i b Num Type Disp Enb Address What 1 breakpoint keep y <MULTIPLE> 1.1 y 0x400583 in test_op_call::operator()(int) at cpls-ops.cc:43 1.2 y 0x40058e in test_op_call::operator()() at cpls-ops.cc:47 1.3 y 0x40059e in test_op_call::operator()(long) at cpls-ops.cc:51 1.4 y 0x4008d0 in test_op_call::operator()<int>(int*) at cpls-ops.cc:57 Similar to how scope lookups work, passing "-qualified" to the break command will cause a literal lookup of the symbol. In the example immediately above, this will cause GDB to only find the three non-template functions.
This commit is contained in:
parent
b05752c223
commit
64a9760601
10 changed files with 800 additions and 40 deletions
82
gdb/utils.c
82
gdb/utils.c
|
@ -2252,13 +2252,45 @@ skip_abi_tag (const char **name)
|
|||
return false;
|
||||
}
|
||||
|
||||
/* If *NAME points at a template parameter list, skip it and return true.
|
||||
Otherwise do nothing and return false. */
|
||||
|
||||
static bool
|
||||
skip_template_parameter_list (const char **name)
|
||||
{
|
||||
const char *p = *name;
|
||||
|
||||
if (*p == '<')
|
||||
{
|
||||
const char *template_param_list_end = find_toplevel_char (p + 1, '>');
|
||||
|
||||
if (template_param_list_end == NULL)
|
||||
return false;
|
||||
|
||||
p = template_param_list_end + 1;
|
||||
|
||||
/* Skip any whitespace that might occur after the closing of the
|
||||
parameter list, but only if it is the end of parameter list. */
|
||||
const char *q = p;
|
||||
while (ISSPACE (*q))
|
||||
++q;
|
||||
if (*q == '>')
|
||||
p = q;
|
||||
*name = p;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* See utils.h. */
|
||||
|
||||
int
|
||||
strncmp_iw_with_mode (const char *string1, const char *string2,
|
||||
size_t string2_len, strncmp_iw_mode mode,
|
||||
enum language language,
|
||||
completion_match_for_lcd *match_for_lcd)
|
||||
completion_match_for_lcd *match_for_lcd,
|
||||
bool ignore_template_params)
|
||||
{
|
||||
const char *string1_start = string1;
|
||||
const char *end_str2 = string2 + string2_len;
|
||||
|
@ -2308,6 +2340,48 @@ strncmp_iw_with_mode (const char *string1, const char *string2,
|
|||
string1++;
|
||||
}
|
||||
|
||||
/* Skip template parameters in STRING1 if STRING2 does not contain
|
||||
any. E.g.:
|
||||
|
||||
Case 1: User is looking for all functions named "foo".
|
||||
string1: foo <...> (...)
|
||||
string2: foo
|
||||
|
||||
Case 2: User is looking for all methods named "foo" in all template
|
||||
class instantiations.
|
||||
string1: Foo<...>::foo <...> (...)
|
||||
string2: Foo::foo (...)
|
||||
|
||||
Case 3: User is looking for a specific overload of a template
|
||||
function or method.
|
||||
string1: foo<...>
|
||||
string2: foo(...)
|
||||
|
||||
Case 4: User is looking for a specific overload of a specific
|
||||
template instantiation.
|
||||
string1: foo<A> (...)
|
||||
string2: foo<B> (...)
|
||||
|
||||
Case 5: User is looking wild parameter match.
|
||||
string1: foo<A<a<b<...> > > > (...)
|
||||
string2: foo<A
|
||||
*/
|
||||
if (language == language_cplus && ignore_template_params
|
||||
&& *string1 == '<' && *string2 != '<')
|
||||
{
|
||||
/* Skip any parameter list in STRING1. */
|
||||
const char *template_start = string1;
|
||||
|
||||
if (skip_template_parameter_list (&string1))
|
||||
{
|
||||
/* Don't mark the parameter list ignored if the user didn't
|
||||
try to ignore it. [Case #5 above] */
|
||||
if (*string2 != '\0'
|
||||
&& match_for_lcd != NULL && template_start != string1)
|
||||
match_for_lcd->mark_ignored_range (template_start, string1);
|
||||
}
|
||||
}
|
||||
|
||||
if (*string1 == '\0' || string2 == end_str2)
|
||||
break;
|
||||
|
||||
|
@ -2416,6 +2490,12 @@ strncmp_iw_with_mode (const char *string1, const char *string2,
|
|||
break;
|
||||
if (*string1 == '(' || *string2 == '(')
|
||||
break;
|
||||
|
||||
/* If STRING1 or STRING2 starts with a template
|
||||
parameter list, break out of operator processing. */
|
||||
skip_ws (string1, string2, end_str2);
|
||||
if (*string1 == '<' || *string2 == '<')
|
||||
break;
|
||||
}
|
||||
|
||||
continue;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue