From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7876 invoked by alias); 18 Apr 2003 19:17:58 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 7869 invoked from network); 18 Apr 2003 19:17:57 -0000 Received: from unknown (HELO papaya.bactrian.org) (216.101.126.244) by sources.redhat.com with SMTP; 18 Apr 2003 19:17:57 -0000 Received: from papaya.bactrian.org (papaya.bactrian.org [127.0.0.1]) by papaya.bactrian.org (8.12.8/8.12.8) with ESMTP id h3IJHsut015471; Fri, 18 Apr 2003 12:17:55 -0700 Received: (from carlton@localhost) by papaya.bactrian.org (8.12.8/8.12.8/Submit) id h3IJHsGn015469; Fri, 18 Apr 2003 12:17:54 -0700 X-Authentication-Warning: papaya.bactrian.org: carlton set sender to carlton@bactrian.org using -f To: gdb-patches@sources.redhat.com Cc: Daniel Jacobowitz Subject: [RFA] handling of 'operator' in cp_find_first_component From: David Carlton Date: Fri, 18 Apr 2003 19:17:00 -0000 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-SW-Source: 2003-04/txt/msg00350.txt.bz2 The function cp_find_first_component assumes that the string 'operator' as part of an operator name can only occur at the start of a component. Unfortunately, this isn't true: I've recently run into situations where there's a templated function whose name demangles to something like int operator<< (char) In particular, the return type is part of the demangled name (I'm not entirely sure why, but that's a separate issue), so 'operator' occurs after a space. This patch modifies cp_find_first_component to accept that; it looks for the string 'operator' either at the beginning of a name or after a few other characters. I've also added some test cases for this. Tested on GCC 3.2, DWARF 2, i686-pc-linux-gnu; no new regressions. OK to commit? David Carlton carlton@bactrian.org 2003-04-18 David Carlton * cp-support.c (cp_find_first_component): Accept 'operator' in more locations. 2003-04-18 David Carlton * gdb.c++/maint.exp (test_first_component): Add tests for 'operator' in more locations. Index: cp-support.c =================================================================== RCS file: /cvs/src/src/gdb/cp-support.c,v retrieving revision 1.2 diff -u -p -r1.2 cp-support.c --- cp-support.c 15 Apr 2003 23:07:11 -0000 1.2 +++ cp-support.c 18 Apr 2003 19:08:55 -0000 @@ -57,16 +57,7 @@ static void first_component_command (cha 'foo' in an anonymous namespace gets demangled as "(anonymous namespace)::foo". - - 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. */ + - And operator names can contain parentheses or angle brackets. */ /* FIXME: carlton/2003-03-13: We have several functions here with overlapping functionality; can we combine them? Also, do they @@ -209,40 +200,14 @@ method_name_from_physname (const char *p unsigned int 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; - - if (strncmp (name, "operator", LENGTH_OF_OPERATOR) == 0) - { - index += LENGTH_OF_OPERATOR; - while (isspace(name[index])) - ++index; - switch (name[index]) - { - 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; - } - } + /* Operator names can show up in unexpected places. Since these can + contain parentheses or angle brackets, they can screw up the + recursion. But not every string 'operator' is part of an + operater name: e.g. you could have a variable 'cooperator'. So + this variable tells us whether or not we should treat the string + 'operator' as starting an operator. */ + int operator_possible = 1; for (;; ++index) { @@ -261,6 +226,7 @@ cp_find_first_component (const char *nam gdb_assert (name[index] == ':'); index += 2; } + operator_possible = 1; break; case '(': /* Similar comment as to '<'. */ @@ -272,13 +238,63 @@ cp_find_first_component (const char *nam gdb_assert (name[index] == ':'); index += 2; } + operator_possible = 1; break; case '>': case ')': case '\0': case ':': 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: + operator_possible = 0; break; } } Index: maint.exp =================================================================== RCS file: /cvs/src/src/gdb/testsuite/gdb.c++/maint.exp,v retrieving revision 1.1 diff -u -p -r1.1 maint.exp --- maint.exp 15 Apr 2003 23:07:11 -0000 1.1 +++ maint.exp 18 Apr 2003 19:10:32 -0000 @@ -63,6 +63,11 @@ proc test_first_component {} { test_single_component "foo(std::basic_streambuf >)" test_single_component "operator>(X::Y)" + # Operator names can show up in weird places. + + test_single_component "int operator<< ()" + test_single_component "T" + 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 C::bar" "C"