2003-04-23 David Carlton <carlton@bactrian.org>

* cp-support.c (cp_find_first_component): Accept 'operator' in
	more locations.

2003-04-23  David Carlton  <carlton@bactrian.org>

	* gdb.c++/maint.exp (test_first_component): Add tests for
	'operator' in more locations.
This commit is contained in:
David Carlton
2003-04-23 23:45:24 +00:00
parent 74cfe982ed
commit 0f20eeea6c
4 changed files with 81 additions and 43 deletions

View File

@ -1,3 +1,8 @@
2003-04-23 David Carlton <carlton@bactrian.org>
* cp-support.c (cp_find_first_component): Accept 'operator' in
more locations.
2003-04-23 Andrew Cagney <cagney@redhat.com> 2003-04-23 Andrew Cagney <cagney@redhat.com>
* infcall.c (call_function_by_hand): Eliminate redundant * infcall.c (call_function_by_hand): Eliminate redundant

View File

@ -57,16 +57,7 @@ static void first_component_command (char *arg, int from_tty);
'foo' in an anonymous namespace gets demangled as "(anonymous 'foo' in an anonymous namespace gets demangled as "(anonymous
namespace)::foo". namespace)::foo".
- And operator names can contain parentheses or angle brackets. - And operator names can contain parentheses or angle brackets. */
Fortunately, I _think_ that operator names can only occur in a
fairly restrictive set of locations (in particular, they have be
at depth 0, don't they?). */
/* NOTE: carlton/2003-02-21: Daniel Jacobowitz came up with an example
where operator names don't occur at depth 0. Sigh. (It involved a
template argument that was a pointer: I hadn't realized that was
possible.) Handling such edge cases does not seem like a
high-priority problem to me. */
/* FIXME: carlton/2003-03-13: We have several functions here with /* FIXME: carlton/2003-03-13: We have several functions here with
overlapping functionality; can we combine them? Also, do they overlapping functionality; can we combine them? Also, do they
@ -209,40 +200,14 @@ method_name_from_physname (const char *physname)
unsigned int unsigned int
cp_find_first_component (const char *name) cp_find_first_component (const char *name)
{ {
/* Names like 'operator<<' screw up the recursion, so let's
special-case them. I _hope_ they can only occur at the start of
a component. */
unsigned int index = 0; unsigned int index = 0;
/* Operator names can show up in unexpected places. Since these can
if (strncmp (name, "operator", LENGTH_OF_OPERATOR) == 0) contain parentheses or angle brackets, they can screw up the
{ recursion. But not every string 'operator' is part of an
index += LENGTH_OF_OPERATOR; operater name: e.g. you could have a variable 'cooperator'. So
while (isspace(name[index])) this variable tells us whether or not we should treat the string
++index; 'operator' as starting an operator. */
switch (name[index]) int operator_possible = 1;
{
case '<':
if (name[index + 1] == '<')
index += 2;
else
index += 1;
break;
case '>':
case '-':
if (name[index + 1] == '>')
index += 2;
else
index += 1;
break;
case '(':
index += 2;
break;
default:
index += 1;
break;
}
}
for (;; ++index) for (;; ++index)
{ {
@ -261,6 +226,7 @@ cp_find_first_component (const char *name)
gdb_assert (name[index] == ':'); gdb_assert (name[index] == ':');
index += 2; index += 2;
} }
operator_possible = 1;
break; break;
case '(': case '(':
/* Similar comment as to '<'. */ /* Similar comment as to '<'. */
@ -272,13 +238,63 @@ cp_find_first_component (const char *name)
gdb_assert (name[index] == ':'); gdb_assert (name[index] == ':');
index += 2; index += 2;
} }
operator_possible = 1;
break; break;
case '>': case '>':
case ')': case ')':
case '\0': case '\0':
case ':': case ':':
return index; return index;
case 'o':
/* Operator names can screw up the recursion. */
if (operator_possible
&& strncmp (name + index, "operator", LENGTH_OF_OPERATOR) == 0)
{
index += LENGTH_OF_OPERATOR;
while (isspace(name[index]))
++index;
switch (name[index])
{
/* Skip over one less than the appropriate number of
characters: the for loop will skip over the last
one. */
case '<':
if (name[index + 1] == '<')
index += 1;
else
index += 0;
break;
case '>':
case '-':
if (name[index + 1] == '>')
index += 1;
else
index += 0;
break;
case '(':
index += 1;
break;
default:
index += 0;
break;
}
}
operator_possible = 0;
break;
case ' ':
case ',':
case '.':
case '&':
case '*':
/* NOTE: carlton/2003-04-18: I'm not sure what the precise
set of relevant characters are here: it's necessary to
include any character that can show up before 'operator'
in a demangled name, and it's safe to include any
character that can't be part of an identifier's name. */
operator_possible = 1;
break;
default: default:
operator_possible = 0;
break; break;
} }
} }

View File

@ -1,3 +1,8 @@
2003-04-23 David Carlton <carlton@bactrian.org>
* gdb.c++/maint.exp (test_first_component): Add tests for
'operator' in more locations.
2003-04-16 Kevin Buettner <kevinb@redhat.com> 2003-04-16 Kevin Buettner <kevinb@redhat.com>
* gdb.base/args.exp: Invoke gdb_load for simulator targets. * gdb.base/args.exp: Invoke gdb_load for simulator targets.

View File

@ -63,6 +63,18 @@ proc test_first_component {} {
test_single_component "foo(std::basic_streambuf<wchar_t,std::char_traits<wchar_t> >)" test_single_component "foo(std::basic_streambuf<wchar_t,std::char_traits<wchar_t> >)"
test_single_component "operator>(X::Y)" test_single_component "operator>(X::Y)"
# Operator names can show up in weird places.
test_single_component "int operator<< <char>()"
test_single_component "T<Cooperator>"
# NOTE: carlton/2003-04-23: I've only seen the first of these
# produced by the demangler, but I'm including two more just to be
# on the safe side.
test_single_component "int foo<&(operator<<(C, C))>()"
test_single_component "int foo<&operator<<(C, C)>()"
test_single_component "int foo<operator<<(C, C)>()"
gdb_test "maint cp first_component foo::bar" "foo" gdb_test "maint cp first_component foo::bar" "foo"
gdb_test "maint cp first_component foo::bar::baz" "foo" gdb_test "maint cp first_component foo::bar::baz" "foo"
gdb_test "maint cp first_component C<A>::bar" "C<A>" gdb_test "maint cp first_component C<A>::bar" "C<A>"