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]

[dictionary] handle 'operator' in more places


This commit to the dictionary branch fixes a couple of misplaced
declarations, and fixes a more serious bug: cp_find_first_component
assumes that 'operator' can only occur after a colon, and that's not
correct.  That affects the mainline as well; I'll post an RFA on the
mainline in a few minutes with more details.  (Also, it adds new test
cases for this issue.)

For anybody who's curious, I've accepted a consulting gig one day a
week for the next two and a half months to improve GDB's C++ namespace
support; that will give me more time to work on both fixing bugs and
merging my branch with mainline, and will give me a situation where
real users are pounding on my branch, to shake out more bugs (like the
one above).  I've got signed copyright transfer statements from them
already.  (The company is named Kealia; bactrian.org is my own
personal domain.)

David Carlton
carlton at bactrian dot org

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

	* mdebugread.c (parse_symbol): Move up declaration of 'iter'.
	* dwarf2read.c (add_partial_namespace): Move up declaration of
	'full_name'.
	* 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.1.2.18
diff -u -p -r1.1.2.18 cp-support.c
--- cp-support.c	16 Apr 2003 19:56:51 -0000	1.1.2.18
+++ cp-support.c	18 Apr 2003 18:08:29 -0000
@@ -95,16 +95,7 @@ static void maintenance_print_namespace 
      '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
@@ -247,40 +238,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)
     {
@@ -299,6 +264,7 @@ cp_find_first_component (const char *nam
 	      gdb_assert (name[index] == ':');
 	      index += 2;
 	    }
+	  operator_possible = 1;
 	  break;
 	case '(':
 	  /* Similar comment as to '<'.  */
@@ -310,13 +276,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 recurson.  */
+	  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: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.66.4.24
diff -u -p -r1.66.4.24 dwarf2read.c
--- dwarf2read.c	16 Apr 2003 19:56:51 -0000	1.66.4.24
+++ dwarf2read.c	18 Apr 2003 18:08:51 -0000
@@ -1686,9 +1686,11 @@ add_partial_namespace (struct partial_di
   /* Calculate the full name of the namespace that we just entered.  */
 
   const char *new_name = pdi->name;
+  char *full_name;
+
   if (new_name == NULL)
     new_name = "(anonymous namespace)";
-  char *full_name = alloca (strlen (namespace) + 2 + strlen (new_name) + 1);
+  full_name = alloca (strlen (namespace) + 2 + strlen (new_name) + 1);
   strcpy (full_name, namespace);
   if (*namespace != '\0')
     strcat (full_name, "::");
Index: mdebugread.c
===================================================================
RCS file: /cvs/src/src/gdb/mdebugread.c,v
retrieving revision 1.29.2.12
diff -u -p -r1.29.2.12 mdebugread.c
--- mdebugread.c	16 Apr 2003 19:56:53 -0000	1.29.2.12
+++ mdebugread.c	18 Apr 2003 18:09:03 -0000
@@ -1231,10 +1231,10 @@ parse_symbol (SYMR *sh, union aux_ext *a
 
 	      if (nparams > 0)
 		{
+		  struct dict_iterator iter;
 		  TYPE_NFIELDS (ftype) = nparams;
 		  TYPE_FIELDS (ftype) = (struct field *)
 		    TYPE_ALLOC (ftype, nparams * sizeof (struct field));
-		  struct dict_iterator iter;
 
 		  for (sym = dict_iterator_first (BLOCK_DICT (b), &iter),
 			 iparams = 0;
Index: testsuite/gdb.c++/maint.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.c++/maint.exp,v
retrieving revision 1.1.2.1
diff -u -p -r1.1.2.1 maint.exp
--- testsuite/gdb.c++/maint.exp	16 Apr 2003 19:57:02 -0000	1.1.2.1
+++ testsuite/gdb.c++/maint.exp	18 Apr 2003 18:09:06 -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]