public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Keith Seitz <keiths@redhat.com>
To: Jan Kratochvil <jan.kratochvil@redhat.com>
Cc: gdb-patches@sourceware.org
Subject: Re: [patch 0/3] Re: [RFA] c++/11734 revisited (and c++/12273)
Date: Tue, 01 Mar 2011 22:00:00 -0000	[thread overview]
Message-ID: <4D6D6C74.8080304@redhat.com> (raw)
In-Reply-To: <20110227211637.GA18378@host1.dyn.jankratochvil.net>

[-- Attachment #1: Type: text/plain, Size: 4102 bytes --]

On 02/27/2011 01:16 PM, Jan Kratochvil wrote:
> On Thu, 24 Feb 2011 21:40:36 +0100, Keith Seitz wrote:
>
> This is still not fixed.  I quoted there the line:
>
>>> +      char *paren = strchr (p, '(');

My bad. I misread your test case. I *think* I've added an appropriate 
test and fixed this for good. Or at least I hope I did. :-D


To summarize the changes in this version:

- Added some more tests based on your input
- Added a new function to collect all this naming stuff that
   started appearing in decode_line_1 and decode_compound.
- Rewrote this naming stuff to remove a bunch of bad/unintended
   assumptions (strchr ('('), whitespace)

I'm sure that some cleanup could be done to this, but as far as I am 
concerned, since this is supposedly blocking the next release, I am not 
in favor of even bigger changes right now, cleanups or rewrites. It's 
just too risky at the moment.

> Maybe some - simplified
> 	while (isspace (*p)) p++;
> 	if (*p == '(')
> would be enough?  I did not try.

Yeah, I added something like that.

> This is also not fixed.  Reproducible by modifying the testcase:
> -	set method "${class}::foo ($ovld) const"
> +	set method "${class}::foo ($ovld)  const"
>
> The problem is the quoted code:
>
>>> +      /* Make sure we keep important kewords like "const" */
>>> +      if (strncmp (p, " const", 6) == 0)
>>> +	p += 6;

I've changed all this. This should now be fixed.

> Also I am suspicious on not checking that !isalnum (p[strlen ("const")]) - that
> there is a word break and isn't there something like:
> 	(gdb) break method(int) constvariablename

I've implemented a check for this case.

> Here isn't tested:
> 	set method "${class}::foo"

I've added this.

I've attached the next revision of this mega-linespec-fixing patch.
Keith

ChangeLog
2011-03-01  Keith Seitz  <keiths@redhat.com>

	* linespec.c (find_methods): Canonicalize NAME before looking
	up the symbol.
	(name_end): New function.
	(is_overloaded): New function.
	(keep_name_info): New function.
	(decode_line_1): Use keep_name_info.
	(decode_compound): Likewise.

	PR c++/12273
	* linespec.c (locate_first_half): Keep overload information, too.
	(decode_compound): Use a string to represent break characters
	to escape the loop.
	If P points to a break character, do not increment it.
	For C++ and Java, keep overload information and relevant keywords.
	If we cannot find a symbol, search the minimal symbols.

	PR c++/11734
	* linespec.c (decode_compound): Rename SAVED_ARG to
	THE_REAL_SAVED_ARG.
	Make a copy of THE_REAL_SAVED_ARG in SAVED_ARG and strip
	single-quotes.
	Pass a valid block to lookup_symbol.
	(lookup_prefix_sym): Likewise.
	(find_method): Construct search name based on SYM_CLASS instead
	of SAVED_ARG.
	* psymtab.c (lookup_partial_symbol): Add language parameter.
	(lookup_symbol_aux_psymtabs): Likewise.
	Don't assume that the psymtab we found was the right one. Search
	for the desired symbol in the symtab to be certain.
	(psymtab_search_name): New function.
	(lookup_partial_symbol): Use psymtab_search_name.
	Add language parameter.
	(read_symtabs_for_function): Add language parameter and pass to
	lookup_partial_symbol.
	(find_symbol_file_from_partial): Likewise.
	* symfile.h (struct quick_symbol_functions): Add language parameter
	to lookup_symbol, expand_symtabs_for_function, and find_symbol_file.
	* cp-support.c (make_symbol_overload_list): Update above API
	changes.
	* symtab.c (lookup_symbol_aux_quick): Pass the current language
	to the quick symbol functions.
	(basic_lookup_transparent_type_quick): Likewise.
	(find_main_filename): Likewise.
	* dwarf2_read.c (dw2_lookup_symbol): Add langauge parameter.
	(dw2_expand_symtabs_for_function): Likewise.
	(dw2_find_symbol_file): Likewise.

testsuite/ChangeLog
2011-03-01  Keith Seitz  <keiths@redhat.com>

	PR c++/12273
	* gdb.cp/cmpd-minsyms.exp: New test.
	* gdb.cp/cmpd-minsyms.cc: New file.

	PR c++/11734
	* gdb.cp/ovsrch.exp: New test.
	* gdb.cp/ovsrch.h: New file.
	* gdb.cp/ovsrch1.cc: New file.
	* gdb.cp/ovsrch2.cc: New file.
	* gdb.cp/ovsrch3.cc: New file.
	* gdb.cp/ovsrch4.cc: New file.

[-- Attachment #2: big-linespec.patch --]
[-- Type: text/plain, Size: 29011 bytes --]

Index: linespec.c
===================================================================
RCS file: /cvs/src/src/gdb/linespec.c,v
retrieving revision 1.110
diff -u -p -r1.110 linespec.c
--- linespec.c	1 Mar 2011 00:26:14 -0000	1.110
+++ linespec.c	1 Mar 2011 21:38:20 -0000
@@ -41,6 +41,7 @@
 #include "mi/mi-cmds.h"
 #include "target.h"
 #include "arch-utils.h"
+#include <ctype.h>
 
 /* We share this one with symtab.c, but it is not exported widely.  */
 
@@ -213,6 +214,19 @@ find_methods (struct type *t, char *name
   int i1 = 0;
   int ibase;
   char *class_name = type_name_no_tag (t);
+  struct cleanup *cleanup;
+  char *canon;
+
+  /* NAME is typed by the user: it needs to be canonicalized before
+     passing to lookup_symbol.  */
+  canon = cp_canonicalize_string (name);
+  if (canon != NULL)
+    {
+      name = canon;
+      cleanup = make_cleanup (xfree, name);
+    }
+  else
+    cleanup = make_cleanup (null_cleanup, NULL);
 
   /* Ignore this class if it doesn't have a name.  This is ugly, but
      unless we figure out how to get the physname without the name of
@@ -275,6 +289,7 @@ find_methods (struct type *t, char *name
       i1 += find_methods (TYPE_BASECLASS (t, ibase), name,
 			  language, sym_arr + i1);
 
+  do_cleanups (cleanup);
   return i1;
 }
 
@@ -663,6 +678,96 @@ find_method_overload_end (char *p)
 
   return p;
 }
+
+/* A helper function for decerning whether the string P contains
+   overload information.  */
+
+static int
+is_overloaded (char *p)
+{
+  /* Locate a parenthesis in P.  */
+  char *paren = strchr (p, '(');
+
+  if (paren != NULL)
+    {
+      /* Locate a (possible) "if" clause.  */
+      char *has_if = strstr (p, "if");
+
+      /* Double-check that the "if" was not part of some sort of name,
+	 by checking the characters before and after the "if".  */
+      if (has_if > p && (isalnum (*(has_if - 1)) || isalnum (*(has_if + 2))))
+	has_if = NULL;
+
+      /* If the "if" was seen after the parenthesis, P points to
+	 an overloaded method.  */
+      if (has_if > paren || has_if == NULL)
+	return 1;
+    }
+
+  /* Otherwise, P does not point to an overloaded method.  */
+  return 0;
+}
+
+
+/* Does P point to a sequence of characters which implies the end
+   of a name?  Terminals include "if" and "thread" clauses. */
+
+static int
+name_end (char *p)
+{
+  while (isspace (*p))
+    ++p;
+  if (*p == 'i' && *(p + 1) == 'f'
+      && (isspace (*(p + 2)) || *(p + 2) == '\0' || *(p + 2) == '('))
+    return 1;
+
+  if (strncmp (p, "thread", 6) == 0
+      && ((isspace (*p + 6)) || *(p + 6) == '\0'))
+    return 1;
+
+  return 0;
+}
+
+/* Keep important information used when looking up a name.  This includes
+   template parameters, overload information, and important keywords.  */
+
+static char *
+keep_name_info (char *ptr)
+{
+  char *p = ptr;
+
+  /* Keep any template parameters.  */
+  if (name_end (ptr))
+    goto done;
+
+  while (isspace (*p))
+    ++p;
+  if (*p == '<')
+    ptr = p = find_template_name_end (ptr);
+
+  if (name_end (ptr))
+    goto done;
+
+  /* Keep method overload information.  */
+  if (is_overloaded (p))
+    ptr = p = find_method_overload_end (p);
+
+  if (name_end (ptr))
+    goto done;
+
+  /* Keep important keywords.  */  
+  while (isspace (*p))
+    ++p;
+  if (strncmp (p, "const", 5) == 0
+      && (isspace (*(p + 5)) || *(p + 5) == '\0' || *(p + 5) == '\''))
+    ptr = p = p + 5;
+
+ done:
+  while (isspace (*(ptr - 1)))
+    --ptr;
+  return ptr;
+}
+
 \f
 /* The parser of linespec itself.  */
 
@@ -871,17 +976,8 @@ decode_line_1 (char **argptr, int funfir
       p = skip_quoted (*argptr);
     }
 
-  /* Keep any template parameters.  */
-  if (*p == '<')
-    p = find_template_name_end (p);
-
-  /* Keep method overload information.  */
-  if (*p == '(')
-    p = find_method_overload_end (p);
-
-  /* Make sure we keep important kewords like "const".  */
-  if (strncmp (p, " const", 6) == 0)
-    p += 6;
+  /* Keep any important naming information.  */
+  p = keep_name_info (p);
 
   copy = (char *) alloca (p - *argptr + 1);
   memcpy (copy, *argptr, p - *argptr);
@@ -1057,6 +1153,10 @@ locate_first_half (char **argptr, int *i
 	    error (_("malformed template specification in command"));
 	  p = temp_end;
 	}
+
+      if (p[0] == '(')
+	p = find_method_overload_end (p);
+
       /* Check for a colon and a plus or minus and a [ (which
          indicates an Objective-C method).  */
       if (is_objc_method_format (p))
@@ -1224,7 +1324,7 @@ decode_objc (char **argptr, int funfirst
 
 static struct symtabs_and_lines
 decode_compound (char **argptr, int funfirstline, char ***canonical,
-		 char *saved_arg, char *p, int *not_found_ptr)
+		 char *the_real_saved_arg, char *p, int *not_found_ptr)
 {
   struct symtabs_and_lines values;
   char *p2;
@@ -1235,6 +1335,23 @@ decode_compound (char **argptr, int funf
   struct symbol *sym_class;
   struct type *t;
   char *saved_java_argptr = NULL;
+  char *saved_arg;
+
+  /* If the user specified any completer quote characters in the input,
+     strip them.  They are superfluous.  */
+  saved_arg = alloca (strlen (the_real_saved_arg) + 1);
+  {
+    char *dst = saved_arg;
+    char *src = the_real_saved_arg;
+    char *quotes = get_gdb_completer_quote_characters ();
+    while (*src != '\0')
+      {
+	if (strchr (quotes, *src) == NULL)
+	  *dst++ = *src;
+	++src;
+      }
+    *dst = '\0';
+  }
 
   /* First check for "global" namespace specification, of the form
      "::foo".  If found, skip over the colons and jump to normal
@@ -1251,8 +1368,10 @@ decode_compound (char **argptr, int funf
         find_method.
 
      2) AAA::inA isn't the name of a class.  In that case, either the
-        user made a typo or AAA::inA is the name of a namespace.
-        Either way, we just look up AAA::inA::fun with lookup_symbol.
+        user made a typo, AAA::inA is the name of a namespace, or it is
+        the name of a minimal symbol.
+        We just look up AAA::inA::fun with lookup_symbol.  If that fails,
+        try lookup_minimal_symbol.
 
      Thus, our first task is to find everything before the last set of
      double-colons and figure out if it's the name of a class.  So we
@@ -1273,6 +1392,8 @@ decode_compound (char **argptr, int funf
 
   while (1)
     {
+      static char *break_characters = " \t(";
+
       /* Move pointer up to next possible class/namespace token.  */
 
       p = p2 + 1;	/* Restart with old value +1.  */
@@ -1283,8 +1404,9 @@ decode_compound (char **argptr, int funf
       /* PASS2: p2->"::fun", p->":fun" */
 
       /* Move pointer ahead to next double-colon.  */
-      while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\'')
-	     && (*p != '('))
+      while (*p
+	     && strchr (break_characters, *p) == NULL
+	     && strchr (get_gdb_completer_quote_characters (), *p) == NULL)
 	{
 	  if (current_language->la_language == language_cplus)
 	    p += cp_validate_operator (p);
@@ -1308,9 +1430,12 @@ decode_compound (char **argptr, int funf
 	  else if ((p[0] == ':') && (p[1] == ':'))
 	    break;	/* Found double-colon.  */
 	  else
-	    /* PASS2: We'll keep getting here, until p->"", at which point
-	       we exit this loop.  */
-	    p++;
+	    {
+	      /* PASS2: We'll keep getting here, until P points to one of the
+		 break characters, at which point we exit this loop.  */
+	      if (*p && strchr (break_characters, *p) == NULL)
+		p++;
+	    }
 	}
 
       if (*p != ':')
@@ -1319,7 +1444,7 @@ decode_compound (char **argptr, int funf
 			   unsuccessfully all the components of the
 			   string, and p->""(PASS2).  */
 
-      /* We get here if p points to ' ', '\t', '\'', "::" or ""(i.e
+      /* We get here if p points to one of the break characters or "" (i.e.,
 	 string ended).  */
       /* Save restart for next time around.  */
       p2 = p;
@@ -1379,18 +1504,8 @@ decode_compound (char **argptr, int funf
 	      p += cp_validate_operator (p - 8) - 8;
 	    }
 
-	  /* Keep any template parameters.  */
-	  if (*p == '<')
-	    p = find_template_name_end (p);
-
-	  /* Keep method overload information.  */
-	  a = strchr (p, '(');
-	  if (a != NULL)
-	    p = find_method_overload_end (a);
-
-	  /* Make sure we keep important kewords like "const".  */
-	  if (strncmp (p, " const", 6) == 0)
-	    p += 6;
+	  /* Keep any important naming information.  */
+	  p = keep_name_info (p);
 
 	  /* Java may append typenames,  so assume that if there is
 	     anything else left in *argptr, it must be a typename.  */
@@ -1470,6 +1585,10 @@ decode_compound (char **argptr, int funf
   /* We couldn't find a class, so we're in case 2 above.  We check the
      entire name as a symbol instead.  */
 
+  if (current_language->la_language == language_cplus
+      || current_language->la_language == language_java)
+      p = keep_name_info (p);
+
   copy = (char *) alloca (p - saved_arg2 + 1);
   memcpy (copy, saved_arg2, p - saved_arg2);
   /* Note: if is_quoted should be true, we snuff out quote here
@@ -1479,15 +1598,24 @@ decode_compound (char **argptr, int funf
   *argptr = (*p == '\'') ? p + 1 : p;
 
   /* Look up entire name.  */
-  sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0);
+  sym = lookup_symbol (copy, get_selected_block (0), VAR_DOMAIN, 0);
   if (sym)
     return symbol_found (funfirstline, canonical, copy, sym, NULL);
+  else
+    {
+      struct minimal_symbol *msym;
+
+      /* Couldn't find any interpretation as classes/namespaces.  As a last
+	 resort, try the minimal symbol tables.  */
+      msym = lookup_minimal_symbol (copy, NULL, NULL);
+      if (msym != NULL)
+	return minsym_found (funfirstline, msym);
+    }    
 
-  /* Couldn't find any interpretation as classes/namespaces, so give
-     up.  The quotes are important if copy is empty.  */
+  /* Couldn't find a minimal symbol, either, so give up.  */
   if (not_found_ptr)
     *not_found_ptr = 1;
-  cplusplus_error (saved_arg,
+  cplusplus_error (the_real_saved_arg,
 		   "Can't find member of namespace, "
 		   "class, struct, or union named \"%s\"\n",
 		   copy);
@@ -1526,7 +1654,7 @@ lookup_prefix_sym (char **argptr, char *
   /* At this point p1->"::inA::fun", p->"inA::fun" copy->"AAA",
      argptr->"inA::fun".  */
 
-  sym = lookup_symbol (copy, 0, STRUCT_DOMAIN, 0);
+  sym = lookup_symbol (copy, get_selected_block (0), STRUCT_DOMAIN, 0);
   if (sym == NULL)
     {
       /* Typedefs are in VAR_DOMAIN so the above symbol lookup will
@@ -1594,20 +1722,32 @@ find_method (int funfirstline, char ***c
       /* If we were given a specific overload instance, use that
 	 (or error if no matches were found).  Otherwise ask the user
 	 which one to use.  */
-      if (strchr (saved_arg, '(') != NULL)
+      if (is_overloaded (saved_arg))
 	{
 	  int i;
-	  char *name = saved_arg;
-	  char *canon = cp_canonicalize_string (name);
+	  char *name;
+	  char *canon;
 	  struct cleanup *cleanup;
 
+	  /* Construct the proper search name based on SYM_CLASS and COPY.
+	     SAVED_ARG may contain a valid name, but that name might not be
+	     what is actually stored in the symbol table.  For example,
+	     if SAVED_ARG (and SYM_CLASS) were found via an import
+	     ("using namespace" in C++), then the physname of
+	     SYM_CLASS ("A::myclass") may not be the same as SAVED_ARG
+	     ("myclass").  */
+	  name = xmalloc (strlen (SYMBOL_NATURAL_NAME (sym_class))
+			  + 2 /* "::" */ + strlen (copy) + 1);
+	  strcpy (name, SYMBOL_NATURAL_NAME (sym_class));
+	  strcat (name, "::");
+	  strcat (name, copy);
+	  canon = cp_canonicalize_string (name);
 	  if (canon != NULL)
 	    {
+	      xfree (name);
 	      name = canon;
-	      cleanup = make_cleanup (xfree, canon);
 	    }
-	  else
-	    cleanup = make_cleanup (null_cleanup, NULL);
+	  cleanup = make_cleanup (xfree, name);
 
 	  for (i = 0; i < i1; ++i)
 	    {
Index: psymtab.c
===================================================================
RCS file: /cvs/src/src/gdb/psymtab.c,v
retrieving revision 1.23
diff -u -p -r1.23 psymtab.c
--- psymtab.c	28 Feb 2011 18:16:59 -0000	1.23
+++ psymtab.c	1 Mar 2011 21:38:20 -0000
@@ -33,6 +33,8 @@
 #include "readline/readline.h"
 #include "gdb_regex.h"
 #include "dictionary.h"
+#include "language.h"
+#include "cp-support.h"
 
 #ifndef DEV_TTY
 #define DEV_TTY "/dev/tty"
@@ -426,7 +428,26 @@ lookup_symbol_aux_psymtabs (struct objfi
   ALL_OBJFILE_PSYMTABS (objfile, ps)
   {
     if (!ps->readin && lookup_partial_symbol (ps, name, psymtab_index, domain))
-      return PSYMTAB_TO_SYMTAB (ps);
+      {
+	struct symbol *sym = NULL;
+	struct symtab *stab = PSYMTAB_TO_SYMTAB (ps);
+
+	/* Some caution must be observed with overloaded functions
+	   and methods, since the psymtab will not contain any overload
+	   information (but NAME might contain it).  */
+	if (stab->primary)
+	  {
+	    struct blockvector *bv = BLOCKVECTOR (stab);
+	    struct block *block = BLOCKVECTOR_BLOCK (bv, block_index);
+
+	    sym = lookup_block_symbol (block, name, domain);
+	  }
+
+	if (sym && strcmp_iw (SYMBOL_SEARCH_NAME (sym), name) == 0)
+	  return stab;
+
+	/* Keep looking through other psymtabs.  */
+      }
   }
 
   return NULL;
@@ -519,6 +540,39 @@ pre_expand_symtabs_matching_psymtabs (st
   /* Nothing.  */
 }
 
+/* Returns the name used to search psymtabs.  Unlike symtabs, psymtabs do
+   not contain any method/function instance information (since this would
+   force reading type information while reading psymtabs).  Therefore,
+   if NAME contains overload information, it must be stripped before searching
+   psymtabs.
+
+   The caller is responsible for freeing the return result.  */
+
+static char *
+psymtab_search_name (const char *name)
+{
+  switch (current_language->la_language)
+    {
+    case language_cplus:
+    case language_java:
+      {
+       if (strchr (name, '('))
+         {
+           char *ret = cp_remove_params (name);
+
+           if (ret)
+             return ret;
+         }
+      }
+      break;
+
+    default:
+      break;
+    }
+
+  return xstrdup (name);
+}
+
 /* Look, in partial_symtab PST, for symbol whose natural name is NAME.
    Check the global symbols if GLOBAL, the static symbols if not.  */
 
@@ -530,11 +584,16 @@ lookup_partial_symbol (struct partial_sy
   struct partial_symbol **top, **real_top, **bottom, **center;
   int length = (global ? pst->n_global_syms : pst->n_static_syms);
   int do_linear_search = 1;
+  char *search_name;
+  struct cleanup *cleanup;
 
   if (length == 0)
     {
       return (NULL);
     }
+
+  search_name = psymtab_search_name (name);
+  cleanup = make_cleanup (xfree, search_name);
   start = (global ?
 	   pst->objfile->global_psymbols.list + pst->globals_offset :
 	   pst->objfile->static_psymbols.list + pst->statics_offset);
@@ -563,7 +622,8 @@ lookup_partial_symbol (struct partial_sy
 	    {
 	      do_linear_search = 1;
 	    }
-	  if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center), name) >= 0)
+	  if (strcmp_iw_ordered (SYMBOL_SEARCH_NAME (*center),
+				 search_name) >= 0)
 	    {
 	      top = center;
 	    }
@@ -577,11 +637,14 @@ lookup_partial_symbol (struct partial_sy
 			_("failed internal consistency check"));
 
       while (top <= real_top
-	     && SYMBOL_MATCHES_SEARCH_NAME (*top, name))
+	     && SYMBOL_MATCHES_SEARCH_NAME (*top, search_name))
 	{
 	  if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
 				     SYMBOL_DOMAIN (*top), domain))
-	    return (*top);
+	    {
+	      do_cleanups (cleanup);
+	      return (*top);
+	    }
 	  top++;
 	}
     }
@@ -595,11 +658,15 @@ lookup_partial_symbol (struct partial_sy
 	{
 	  if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
 				     SYMBOL_DOMAIN (*psym), domain)
-	      && SYMBOL_MATCHES_SEARCH_NAME (*psym, name))
-	    return (*psym);
+	      && SYMBOL_MATCHES_SEARCH_NAME (*psym, search_name))
+	    {
+	      do_cleanups (cleanup);
+	      return (*psym);
+	    }
 	}
     }
 
+  do_cleanups (cleanup);
   return (NULL);
 }
 
Index: testsuite/gdb.cp/cmpd-minsyms.cc
===================================================================
RCS file: testsuite/gdb.cp/cmpd-minsyms.cc
diff -N testsuite/gdb.cp/cmpd-minsyms.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/cmpd-minsyms.cc	1 Mar 2011 21:38:20 -0000
@@ -0,0 +1,37 @@
+/* This test case is part of GDB, the GNU debugger.
+
+   Copyright 2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+template <typename T>
+class GDB
+{
+ public:
+   static int simple (void) { return 0; }
+   static int harder (T a) { return 1; }
+   template <typename X>
+   static X even_harder (T a) { return static_cast<X> (a); }
+   int operator == (GDB const& other)
+   { return 1; }
+};
+
+int main(int argc, char **argv)
+{
+   GDB<int> a, b;
+   if (a == b)
+     return GDB<char>::harder('a') + GDB<int>::harder(3)
+	+ GDB<char>::even_harder<int> ('a');
+   return GDB<int>::simple ();
+}
Index: testsuite/gdb.cp/cmpd-minsyms.exp
===================================================================
RCS file: testsuite/gdb.cp/cmpd-minsyms.exp
diff -N testsuite/gdb.cp/cmpd-minsyms.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/cmpd-minsyms.exp	1 Mar 2011 21:38:20 -0000
@@ -0,0 +1,50 @@
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# Contributed by Red Hat, originally written by Keith Seitz.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite.
+
+if {[skip_cplus_tests]} { continue }
+
+# Test for c++/12273
+set testfile "cmpd-minsyms"
+# Do NOT compile with debug flag.
+if {[prepare_for_testing $testfile $testfile $testfile.cc {c++}]} {
+    return -1
+}
+
+gdb_test_no_output "set language c++"
+
+# A list of minimal symbol names to check.
+# Note that GDB<char>::even_harder<int>(char) is quoted and includes
+# the return type.  This is necessary because this is the demangled name
+# of the minimal symbol.
+set min_syms [list \
+		  "GDB<int>::operator ==" \
+		  "GDB<int>::operator==(GDB<int> const&)" \
+		  "GDB<char>::harder(char)" \
+		  "GDB<int>::harder(int)" \
+		  {"int GDB<char>::even_harder<int>(char)"} \
+		  "GDB<int>::simple()"]
+
+foreach sym $min_syms {
+    set tst "setting breakpoint at $sym"
+    if {[gdb_breakpoint $sym]} {
+	pass $tst
+    }
+}
+
+gdb_exit
Index: testsuite/gdb.cp/ovsrch.exp
===================================================================
RCS file: testsuite/gdb.cp/ovsrch.exp
diff -N testsuite/gdb.cp/ovsrch.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/ovsrch.exp	1 Mar 2011 21:38:20 -0000
@@ -0,0 +1,100 @@
+# Copyright 2011 Free Software Foundation, Inc.
+#
+# Contributed by Red Hat, originally written by Keith Seitz.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the gdb testsuite.
+
+proc test_class {class} {
+
+    # An array holding the overload types for the methods A::outer::foo
+    # and A::B::inner::foo.  The first element is the overloaded method
+    # parameter.  The second element is the expected source file number,
+    # e.g. "ovsrch?.cc".
+    array set tests {
+	"char*"  4
+	"int"    3
+	"void"   2
+    }
+
+    # Test each overload instance twice: once quoted, once unquoted
+    set conditional1 "if (a == 3)"
+    set conditional2 "if (A::outer::func ())"
+    foreach ovld [array names tests] {
+	set method "${class}::foo  ($ovld)  const"
+	set result "Breakpoint (\[0-9\]).*file .*/ovsrch$tests($ovld).*"
+	gdb_test "break $method" $result
+	gdb_test "break '$method'" $result
+
+	# Also test with a conditional tacked onto the end.
+	if {[string compare $ovld "void"] != 0} {
+	    gdb_test "break $method $conditional1" $result
+	    gdb_test "break '$method' $conditional1" $result
+	    gdb_test "break $method $conditional2" $result
+	    gdb_test "break '$method' $conditional2" $result
+	}
+    }
+
+    # Test whether open parentheses are correctly identified as overload
+    # information or conditional.
+    gdb_test "break ${class}::foo if (a == 3)" "Breakpoint (\[0-9\]).*"
+}
+
+if { [skip_cplus_tests] } { continue }
+
+# Test for c++/11734
+set testfile "ovsrch"
+set binfile [file join $objdir $subdir $testfile]
+
+set srcfiles {}
+for {set i 1} {$i < 5} {incr i} {
+    lappend srcfiles $testfile$i.cc
+}
+
+if {[prepare_for_testing $testfile $testfile $srcfiles {c++ debug}]} {
+    return -1
+}
+
+if {![runto_main]} {
+    perror "couldn't run to breakpoint"
+    continue
+}
+
+# Break in A::stop_here and run tests.
+if {[gdb_breakpoint "stop_here"]} {
+    pass "break stop_here"
+}
+
+if {[gdb_breakpoint "'stop_here'"]} {
+    pass "break 'stop_here'"
+}
+
+gdb_continue_to_breakpoint "stop_here"
+test_class outer
+
+# Break in A::B::stop_here_too and run tests.
+if {[gdb_breakpoint "B::stop_here_too"]} {
+    pass "break B::stop_here_too"
+}
+
+if {[gdb_breakpoint "'B::stop_here_too'"]} {
+    pass "break 'B::stop_here_too'"
+}
+
+gdb_continue_to_breakpoint "stop_here_too"
+test_class inner
+
+gdb_exit
+return 0
Index: testsuite/gdb.cp/ovsrch.h
===================================================================
RCS file: testsuite/gdb.cp/ovsrch.h
diff -N testsuite/gdb.cp/ovsrch.h
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/ovsrch.h	1 Mar 2011 21:38:20 -0000
@@ -0,0 +1,39 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+namespace A
+{
+  class outer
+  {
+  public:
+    void foo (void) const;
+    void foo (int) const;
+    void foo (char *) const;
+    bool func (void) { return true; }
+  };
+
+  namespace B
+  {
+    class inner
+    {
+    public:
+      void foo (void) const;
+      void foo (int) const;
+      void foo (char *) const;
+    };
+  }
+}
Index: testsuite/gdb.cp/ovsrch1.cc
===================================================================
RCS file: testsuite/gdb.cp/ovsrch1.cc
diff -N testsuite/gdb.cp/ovsrch1.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/ovsrch1.cc	1 Mar 2011 21:38:20 -0000
@@ -0,0 +1,41 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "ovsrch.h"
+
+namespace A
+{
+  void stop_here (void) { }
+
+  namespace B
+  {
+    void stop_here_too (void) { }
+  }
+}
+
+using namespace A;
+
+int
+main ()
+{
+  outer *p = new outer;
+  stop_here ();
+  B::stop_here_too ();
+  p->foo ();
+  return 0;
+}
+
Index: testsuite/gdb.cp/ovsrch2.cc
===================================================================
RCS file: testsuite/gdb.cp/ovsrch2.cc
diff -N testsuite/gdb.cp/ovsrch2.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/ovsrch2.cc	1 Mar 2011 21:38:20 -0000
@@ -0,0 +1,28 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "ovsrch.h"
+
+void
+A::outer::foo (void) const
+{
+}
+
+void
+A::B::inner::foo (void) const
+{
+}
Index: testsuite/gdb.cp/ovsrch3.cc
===================================================================
RCS file: testsuite/gdb.cp/ovsrch3.cc
diff -N testsuite/gdb.cp/ovsrch3.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/ovsrch3.cc	1 Mar 2011 21:38:20 -0000
@@ -0,0 +1,28 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "ovsrch.h"
+
+void
+A::outer::foo (int a) const
+{
+}
+
+void
+A::B::inner::foo (int a) const
+{
+}
Index: testsuite/gdb.cp/ovsrch4.cc
===================================================================
RCS file: testsuite/gdb.cp/ovsrch4.cc
diff -N testsuite/gdb.cp/ovsrch4.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/ovsrch4.cc	1 Mar 2011 21:38:20 -0000
@@ -0,0 +1,28 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2011 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "ovsrch.h"
+
+void
+A::outer::foo (char *a) const
+{
+}
+
+void
+A::B::inner::foo (char *a) const
+{
+}

  reply	other threads:[~2011-03-01 22:00 UTC|newest]

Thread overview: 29+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-12-09  0:50 [RFA] c++/11734 revisited Keith Seitz
2010-12-09  4:02 ` Eli Zaretskii
2010-12-09 21:45 ` Tom Tromey
2010-12-09 21:52   ` Jan Kratochvil
2010-12-10 15:21     ` Keith Seitz
2010-12-14 20:03   ` Keith Seitz
2011-01-24 18:15     ` Jan Kratochvil
2011-01-26 23:14       ` Jan Kratochvil
2011-02-06 22:04     ` Jan Kratochvil
2011-02-06 22:45     ` [patch 0/3] Re: [RFA] c++/11734 revisited (and c++/12273) Jan Kratochvil
2011-02-08 21:42       ` Tom Tromey
2011-02-10 21:45       ` Keith Seitz
2011-02-17 18:37         ` Keith Seitz
2011-02-18  3:24           ` Keith Seitz
2011-02-21 11:41           ` Jan Kratochvil
2011-02-24 20:41             ` Keith Seitz
2011-02-27 21:18             ` Jan Kratochvil
2011-03-01 22:00               ` Keith Seitz [this message]
2011-03-14  7:52                 ` Jan Kratochvil
2011-03-15 19:03                   ` Keith Seitz
2011-03-16  8:28                     ` Jan Kratochvil
2011-03-16 13:58                       ` Tom Tromey
2011-03-16 23:20                       ` Keith Seitz
2011-03-17  3:19                         ` Joel Brobecker
2011-03-17  9:11                           ` Jan Kratochvil
2011-03-17 13:21                             ` Joel Brobecker
2011-02-06 22:46     ` [patch 2/3] Keith's psymtabs fix [Re: [RFA] c++/11734 revisited] Jan Kratochvil
2011-02-06 22:46     ` [patch 3/3] Various linespec fixups " Jan Kratochvil
2011-02-06 22:46     ` [patch 1/3] revert physname part (b) " Jan Kratochvil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=4D6D6C74.8080304@redhat.com \
    --to=keiths@redhat.com \
    --cc=gdb-patches@sourceware.org \
    --cc=jan.kratochvil@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).