This is the mail archive of the gdb-patches@sources.redhat.com mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[RFA] handling of 'operator' in cp_find_first_component


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<< <int>(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 at bactrian dot org

2003-04-18  David Carlton  <carlton at bactrian dot org>

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

2003-04-18  David Carlton  <carlton at bactrian dot org>

	* 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<wchar_t,std::char_traits<wchar_t> >)"
     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>"
+
     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<A>::bar" "C<A>"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]