Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* [RFA 2/4] dwarf2_physname
@ 2009-11-20 21:20 Keith Seitz
  2009-11-20 22:10 ` Daniel Jacobowitz
                   ` (2 more replies)
  0 siblings, 3 replies; 50+ messages in thread
From: Keith Seitz @ 2009-11-20 21:20 UTC (permalink / raw)
  To: gdb-patches

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

Hi,

It turns out I lied: there are really four parts to this patchset. O:-)

The attached patch is the real "meat and potatoes" of the thing. It 
includes much of the earlier patches that I posted on August 31, except 
that this leaves out none of the details.

I refer the interested reader to the earlier thread on this idea of 
constructing physnames for C++ symbols:

http://sourceware.org/ml/gdb-patches/2009-08/msg00593.html

Some warnings are in order. First, this is probably going to really slow 
down large C++ applications, because we no longer use 
DW_AT_MIPS_linkage_name as generated from the compiler. We essentially 
build this name during DIE reading.

I have not made any attempt yet to straighten out SYMBOL_NATURAL_NAME, 
SYMBOL_PRINT_NAME, etc. I expect to do that in a follow-on patchset.

There are now two regressions in cp-namespace.exp (and two new passes). 
These regressions work on archer-keiths-expr-cumulative, so I am 
guessing that Sami's namespace work there (which relies on 
dwarf2_physname) fixes those tests. He will follow-up on that at the 
appropriate time.

Finally, there are two new java failures. IMO given the current 
atmosphere, these are not a big deal. "break 
foo.main(java.lang.String[])" no longer works. You must use the 
alternate "break foo.main(java.lang.String[])void". Previously, either 
of these would work. [It could perhaps be made to work, but I didn't 
bother. I am less interested in keeping gdb working on java than I am ada.]

With those caveats out of the way, I will say that I understand there 
are some controversial changes in here: it is a pretty big paradigm 
shift for the dwarf reader. Nonetheless, the benefits outweigh the 
performance degradation (for C++ ONLY) and the minor java regression. 
IMO, the elimination of single-quoting for C++ expressions alone is 
worth it.

Questions/comments/concerns?
Keith

ChangeLog
2009-11-20  Keith Seitz  <keiths@redhat.com>

         Based on work from Daniel Jacobowitz  <dan@codesourcery.com>:
         * c-typeprint.c (cp_type_print_method_args): For non-static 
methods,
         print out const or volatile qualifiers, too.
         (c_type_print_args): Add parameters show_artificial and language.
         Skip artificial parameters when requested.
         Use the appropriate language printer.
         (c_type_print_varspec): Tell c_type_print_args to skip artificial
         parameters and pass language_c.
         * dwarf2read.c (die_list): New file global.
         (struct partial_die_info): Update comments for name field.
         (pdi_needs_namespace): Renamed to ...
         (die_needs_namespace): ... this. Rewrite.
         (dwarf2_linkage_name): Remove.
         (add_partial_symbol): Do not predicate the call to
         partial_die_full_name based on pdi_needs_namespace.
         Remove call to cp_check_possible_namespace_symbols and associated
         outdated comments.
         (guess_structure_name): Do not inspect child subprogram DIEs.
         (dwarf2_fullname): Update comments.
         Use die_needs_namespace to assist in computing the name.
         (read_func_scope): Use dwarf2_name to get the DIE's name.
         Use dwarf2_physname to get the "linkage name" of the DIE.
         (dwarf2_add_member_field): Use dwarf2_physname instead of
         dwarf2_linkage_name.
         (read_structure_type): For structs and classes, set TYPE_NAME, too.
         (determine_class): Remove.
         (read_partial_die): Ignore DW_AT_MIPS_linkage_name for all 
languages
         except Ada.
         (new_symbol): Unconditionally call dwarf2_name.
         Compute the "linkage name" using dwarf2_physname.
         Use dwarf2_name instead of dwarf2_full_name for enumerator DIEs.
         When determining to scan for anonymous C++ namespaces, ignore
         the linkage name.
         (physname_prefix): New function.
         (physname_prefix_1): New function.
         (dwarf2_physname): New function.
         (_initialize_dwarf2_read): Initialize die_list.
         * gnu-v3-eabi.c (gnu_v3_find_method_in): Remove unused variable
         physname.
         (gnu_v3_print_method_ptr): Use the physname for virtual methods
         without a demangled name.
         Print out type information for non-virtual methods.
         * symtab.c (symbol_find_demangled_name): Add DMGL_VERBOSE flag
         to cplus_demangle.
         * linespec.c (decode_line_1): Keep important keywords like
         "const" and "volatile".
         * symtab.h (SYMBOL_CPLUS_DEMANGLED_NAME): Remove.
         * utils.c (strcmp_iw): Add yet another hack for dealing
         with qualifiers const and volatile.
         * typeprint.h (c_type_print_args): Add declaration.
         * ui-file.c (do_ui_file_obsavestring): New function.
         (ui_file_obsavestring): New function.
         * ui-file.h (ui_file_obsavestring): Add declaration.
         * valops.c (find_overload_match): Resolve the object to
         a non-pointer type.
         If the object is a data member, search the object for the member
         and return with staticp set.
         Use SYMBOL_NATURAL_NAME instead of SYMBOL_CPLUS_DEMANGLED_NAME.
         Do not attempt to extract a function name from non-function types.
         If the extracted function name and the original name are the same,
         we don't have a C++ method.

[-- Attachment #2: dwarf2_physname.patch --]
[-- Type: text/plain, Size: 31111 bytes --]

Index: c-typeprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-typeprint.c,v
retrieving revision 1.49
diff -u -p -r1.49 c-typeprint.c
--- c-typeprint.c	12 Nov 2009 19:47:25 -0000	1.49
+++ c-typeprint.c	19 Nov 2009 23:53:55 -0000
@@ -32,6 +32,7 @@
 #include "c-lang.h"
 #include "typeprint.h"
 #include "cp-abi.h"
+#include "jv-lang.h"
 
 #include "gdb_string.h"
 #include <errno.h>
@@ -40,8 +41,6 @@ static void cp_type_print_method_args (s
 				       char *varstring, int staticp,
 				       struct ui_file *stream);
 
-static void c_type_print_args (struct type *, struct ui_file *);
-
 static void cp_type_print_derivation_info (struct ui_file *, struct type *);
 
 static void c_type_print_varspec_prefix (struct type *, struct ui_file *, int,
@@ -197,6 +196,23 @@ cp_type_print_method_args (struct type *
     fprintf_filtered (stream, "void");
 
   fprintf_filtered (stream, ")");
+
+  /* For non-static methods, read qualifiers from the type of
+     THIS.  */
+  if (!staticp)
+    {
+      struct type *domain;
+
+      gdb_assert (nargs > 0);
+      gdb_assert (TYPE_CODE (args[0].type) == TYPE_CODE_PTR);
+      domain = TYPE_TARGET_TYPE (args[0].type);
+
+      if (TYPE_CONST (domain))
+	fprintf_filtered (stream, " const");
+
+      if (TYPE_VOLATILE (domain))
+	fprintf_filtered (stream, " volatile");
+    }
 }
 
 
@@ -353,10 +369,14 @@ c_type_print_modifier (struct type *type
 
 /* Print out the arguments of TYPE, which should have TYPE_CODE_METHOD
    or TYPE_CODE_FUNC, to STREAM.  Artificial arguments, such as "this"
-   in non-static methods, are displayed.  */
+   in non-static methods, are displayed if SHOW_ARTIFICIAL is
+   non-zero. LANGUAGE is the language in which TYPE was defined.  This is
+   a necessary evil since this code is used by the C, C++, and Java
+   backends. */
 
-static void
-c_type_print_args (struct type *type, struct ui_file *stream)
+void
+c_type_print_args (struct type *type, struct ui_file *stream,
+		   int show_artificial, enum language language)
 {
   int i, len;
   struct field *args;
@@ -368,13 +388,19 @@ c_type_print_args (struct type *type, st
 
   for (i = 0; i < TYPE_NFIELDS (type); i++)
     {
+      if (TYPE_FIELD_ARTIFICIAL (type, i) && !show_artificial)
+	continue;
+
       if (printed_any)
 	{
 	  fprintf_filtered (stream, ", ");
 	  wrap_here ("    ");
 	}
 
-      c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
+      if (language == language_java)
+	java_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
+      else
+	c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
       printed_any = 1;
     }
 
@@ -591,7 +617,7 @@ c_type_print_varspec_suffix (struct type
       if (passed_a_ptr)
 	fprintf_filtered (stream, ")");
       if (!demangled_args)
-	c_type_print_args (type, stream);
+	c_type_print_args (type, stream, 1, language_c);
       c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show,
 				   passed_a_ptr, 0);
       break;
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.338
diff -u -p -r1.338 dwarf2read.c
--- dwarf2read.c	16 Nov 2009 18:40:21 -0000	1.338
+++ dwarf2read.c	19 Nov 2009 23:53:58 -0000
@@ -48,6 +48,9 @@
 #include "gdbcmd.h"
 #include "block.h"
 #include "addrmap.h"
+#include "typeprint.h"
+#include "jv-lang.h"
+#include "vec.h"
 
 #include <fcntl.h>
 #include "gdb_string.h"
@@ -484,8 +487,7 @@ struct partial_die_info
     unsigned int has_byte_size : 1;
 
     /* The name of this DIE.  Normally the value of DW_AT_name, but
-       sometimes DW_TAG_MIPS_linkage_name or a string computed in some
-       other fashion.  */
+       sometimes a default name for unnamed DIEs.  */
     char *name;
 
     /* The scope to prepend to our children.  This is generally
@@ -674,6 +676,11 @@ struct field_info
     int nfnfields;
   };
 
+/* A vector used during linkage name generation.  */
+typedef struct die_info *die_info_p;
+DEF_VEC_P (die_info_p);
+static VEC(die_info_p) *die_list;
+
 /* One item on the queue of compilation units to read in full symbols
    for.  */
 struct dwarf2_queue_item
@@ -785,7 +792,7 @@ static void scan_partial_symbols (struct
 static void add_partial_symbol (struct partial_die_info *,
 				struct dwarf2_cu *);
 
-static int pdi_needs_namespace (enum dwarf_tag tag);
+static int die_needs_namespace (struct die_info *, struct dwarf2_cu *);
 
 static void add_partial_namespace (struct partial_die_info *pdi,
 				   CORE_ADDR *lowpc, CORE_ADDR *highpc,
@@ -930,6 +937,11 @@ static struct type *tag_type_to_type (st
 
 static struct type *read_type_die (struct die_info *, struct dwarf2_cu *);
 
+static char *physname_prefix (struct die_info *die, struct dwarf2_cu *);
+
+static void physname_prefix_1 (struct ui_file *, struct die_info *,
+			       struct dwarf2_cu *);
+
 static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
 
 static char *typename_concat (struct obstack *,
@@ -974,9 +986,6 @@ static void dwarf2_attach_fn_fields_to_t
 
 static void process_structure_scope (struct die_info *, struct dwarf2_cu *);
 
-static const char *determine_class_name (struct die_info *die,
-					 struct dwarf2_cu *cu);
-
 static void read_common_block (struct die_info *, struct dwarf2_cu *);
 
 static void read_namespace (struct die_info *die, struct dwarf2_cu *);
@@ -1018,7 +1027,7 @@ static gdb_byte *read_full_die (const st
 
 static void process_die (struct die_info *, struct dwarf2_cu *);
 
-static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
+static char *dwarf2_physname (struct die_info *, struct dwarf2_cu *);
 
 static char *dwarf2_canonicalize_name (char *, struct dwarf2_cu *,
 				       struct obstack *);
@@ -2438,12 +2447,9 @@ add_partial_symbol (struct partial_die_i
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  if (pdi_needs_namespace (pdi->tag))
-    {
-      actual_name = partial_die_full_name (pdi, cu);
-      if (actual_name)
-	built_actual_name = 1;
-    }
+  actual_name = partial_die_full_name (pdi, cu);
+  if (actual_name)
+    built_actual_name = 1;
 
   if (actual_name == NULL)
     actual_name = pdi->name;
@@ -2583,34 +2589,17 @@ add_partial_symbol (struct partial_die_i
       break;
     }
 
-  /* Check to see if we should scan the name for possible namespace
-     info.  Only do this if this is C++, if we don't have namespace
-     debugging info in the file, if the psym is of an appropriate type
-     (otherwise we'll have psym == NULL), and if we actually had a
-     mangled name to begin with.  */
-
-  /* FIXME drow/2004-02-22: Why don't we do this for classes, i.e. the
-     cases which do not set PSYM above?  */
-
-  if (cu->language == language_cplus
-      && cu->has_namespace_info == 0
-      && psym != NULL
-      && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
-    cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym),
-					 objfile);
-
   if (built_actual_name)
     xfree (actual_name);
 }
 
-/* Determine whether a die of type TAG living in a C++ class or
-   namespace needs to have the name of the scope prepended to the
-   name listed in the die.  */
+/* Determine whether DIE needs to have the name of the scope prepended
+   to the name listed in the die.  */
 
 static int
-pdi_needs_namespace (enum dwarf_tag tag)
+die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu)
 {
-  switch (tag)
+  switch (die->tag)
     {
     case DW_TAG_namespace:
     case DW_TAG_typedef:
@@ -2620,7 +2609,23 @@ pdi_needs_namespace (enum dwarf_tag tag)
     case DW_TAG_union_type:
     case DW_TAG_enumeration_type:
     case DW_TAG_enumerator:
+    case DW_TAG_subprogram:
+    case DW_TAG_member:
       return 1;
+
+    case DW_TAG_variable:
+      {
+	struct attribute *attr;
+	attr = dwarf2_attr (die, DW_AT_specification, cu);
+	if (attr)
+	  return 1;
+	attr = dwarf2_attr (die, DW_AT_external, cu);
+	if (attr == NULL && die->parent->tag != DW_TAG_namespace)
+	  return 0;
+	return 1;
+      }
+      break;
+
     default:
       return 0;
     }
@@ -2749,27 +2754,6 @@ guess_structure_name (struct partial_die
 
       if (real_pdi->die_parent != NULL)
 	return;
-
-      while (child_pdi != NULL)
-	{
-	  if (child_pdi->tag == DW_TAG_subprogram)
-	    {
-	      char *actual_class_name
-		= language_class_name_from_physname (cu->language_defn,
-						     child_pdi->name);
-	      if (actual_class_name != NULL)
-		{
-		  struct_pdi->name
-		    = obsavestring (actual_class_name,
-				    strlen (actual_class_name),
-				    &cu->comp_unit_obstack);
-		  xfree (actual_class_name);
-		}
-	      break;
-	    }
-
-	  child_pdi = child_pdi->die_sibling;
-	}
     }
 }
 
@@ -3337,37 +3321,52 @@ process_die (struct die_info *die, struc
 /* Return the fully qualified name of DIE, based on its DW_AT_name.
    If scope qualifiers are appropriate they will be added.  The result
    will be allocated on the objfile_obstack, or NULL if the DIE does
-   not have a name.  */
+   not have a name.
+
+   The output string will be canonicalized (if C++/Java). */
 
 static const char *
 dwarf2_full_name (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct attribute *attr;
-  char *prefix, *name;
-  struct ui_file *buf = NULL;
+  char *name;
 
   name = dwarf2_name (die, cu);
-  if (!name)
-    return NULL;
 
   /* These are the only languages we know how to qualify names in.  */
-  if (cu->language != language_cplus
-      && cu->language != language_java)
-    return name;
+  if (name != NULL
+      && (cu->language == language_cplus || cu->language == language_java))
+    {
+      if (die_needs_namespace (die, cu))
+	{
+	  long length;
+	  char *prefix;
+	  struct ui_file *buf;
+
+	  buf = mem_fileopen ();
+	  prefix = determine_prefix (die, cu);
+	  if (*prefix != '\0')
+	    {
+	      char *prefixed_name = typename_concat (NULL, prefix, name, cu);
+	      fputs_unfiltered (prefixed_name, buf);
+	      xfree (prefixed_name);
+	    }
+	  else
+	    fputs_unfiltered (name, buf);
 
-  /* If no prefix is necessary for this type of DIE, return the
-     unqualified name.  The other three tags listed could be handled
-     in pdi_needs_namespace, but that requires broader changes.  */
-  if (!pdi_needs_namespace (die->tag)
-      && die->tag != DW_TAG_subprogram
-      && die->tag != DW_TAG_variable
-      && die->tag != DW_TAG_member)
-    return name;
+	  name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack,
+				       &length);
+	  ui_file_delete (buf);
 
-  prefix = determine_prefix (die, cu);
-  if (*prefix != '\0')
-    name = typename_concat (&cu->objfile->objfile_obstack, prefix,
-			    name, cu);
+	  if (cu->language == language_cplus)
+	    {
+	      char *cname
+		= dwarf2_canonicalize_name (name, cu,
+					    &cu->objfile->objfile_obstack);
+	      if (cname != NULL)
+		name = cname;
+	    }
+	}
+    }
 
   return name;
 }
@@ -3840,7 +3839,7 @@ read_func_scope (struct die_info *die, s
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  name = dwarf2_linkage_name (die, cu);
+  name = dwarf2_name (die, cu);
 
   /* Ignore functions with missing or empty names and functions with
      missing or invalid low and high pc attributes.  */
@@ -4514,7 +4513,7 @@ dwarf2_add_field (struct field_info *fip
 	return;
 
       /* Get physical name.  */
-      physname = dwarf2_linkage_name (die, cu);
+      physname = dwarf2_physname (die, cu);
 
       /* The name is already allocated along with this objfile, so we don't
 	 need to duplicate it for the type.  */
@@ -4669,7 +4668,7 @@ dwarf2_add_member_fn (struct field_info 
     return;
 
   /* Get the mangled name.  */
-  physname = dwarf2_linkage_name (die, cu);
+  physname = dwarf2_physname (die, cu);
 
   /* Look up member function name in fieldlist.  */
   for (i = 0; i < fip->nfnfields; i++)
@@ -4997,14 +4996,18 @@ read_structure_type (struct die_info *di
       if (cu->language == language_cplus
 	  || cu->language == language_java)
 	{
-	  const char *new_prefix = determine_class_name (die, cu);
-	  TYPE_TAG_NAME (type) = (char *) new_prefix;
+	  TYPE_TAG_NAME (type) = (char *) dwarf2_full_name (die, cu);
+	  if (die->tag == DW_TAG_structure_type
+	      || die->tag == DW_TAG_class_type)
+	    TYPE_NAME (type) = TYPE_TAG_NAME (type);
 	}
       else
 	{
 	  /* The name is already allocated along with this objfile, so
 	     we don't need to duplicate it for the type.  */
-	  TYPE_TAG_NAME (type) = name;
+	  TYPE_TAG_NAME (type) = (char *) name;
+	  if (die->tag == DW_TAG_class_type)
+	    TYPE_NAME (type) = TYPE_TAG_NAME (type);
 	}
     }
 
@@ -5243,51 +5246,6 @@ read_enumeration_type (struct die_info *
   return set_die_type (die, type, cu);
 }
 
-/* Determine the name of the type represented by DIE, which should be
-   a named C++ or Java compound type.  Return the name in question,
-   allocated on the objfile obstack.  */
-
-static const char *
-determine_class_name (struct die_info *die, struct dwarf2_cu *cu)
-{
-  const char *new_prefix = NULL;
-
-  /* If we don't have namespace debug info, guess the name by trying
-     to demangle the names of members, just like we did in
-     guess_structure_name.  */
-  if (!processing_has_namespace_info)
-    {
-      struct die_info *child;
-
-      for (child = die->child;
-	   child != NULL && child->tag != 0;
-	   child = sibling_die (child))
-	{
-	  if (child->tag == DW_TAG_subprogram)
-	    {
-	      char *phys_prefix
-		= language_class_name_from_physname (cu->language_defn,
-						     dwarf2_linkage_name
-						     (child, cu));
-
-	      if (phys_prefix != NULL)
-		{
-		  new_prefix
-		    = obsavestring (phys_prefix, strlen (phys_prefix),
-				    &cu->objfile->objfile_obstack);
-		  xfree (phys_prefix);
-		  break;
-		}
-	    }
-	}
-    }
-
-  if (new_prefix == NULL)
-    new_prefix = dwarf2_full_name (die, cu);
-
-  return new_prefix;
-}
-
 /* Given a pointer to a die which begins an enumeration, process all
    the dies that define the members of the enumeration, and create the
    symbol for the enumeration type.
@@ -6754,7 +6712,8 @@ read_partial_die (struct partial_die_inf
 	    }
 	  break;
 	case DW_AT_MIPS_linkage_name:
-	  part_die->name = DW_STRING (&attr);
+	  if (cu->language == language_ada)
+	    part_die->name = DW_STRING (&attr);
 	  break;
 	case DW_AT_low_pc:
 	  has_low_pc_attr = 1;
@@ -8319,13 +8278,11 @@ new_symbol (struct die_info *die, struct
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  if (die->tag != DW_TAG_namespace)
-    name = dwarf2_linkage_name (die, cu);
-  else
-    name = TYPE_NAME (type);
-
+  name = dwarf2_name (die, cu);
   if (name)
     {
+      const char *linkagename;
+
       sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
 					     sizeof (struct symbol));
       OBJSTAT (objfile, n_syms++);
@@ -8333,7 +8290,8 @@ new_symbol (struct die_info *die, struct
 
       /* Cache this symbol's name and the name's demangled form (if any).  */
       SYMBOL_LANGUAGE (sym) = cu->language;
-      SYMBOL_SET_NAMES (sym, name, strlen (name), 0, objfile);
+      linkagename = dwarf2_physname (die, cu);
+      SYMBOL_SET_NAMES (sym, linkagename, strlen (linkagename), 0, objfile);
 
       /* Default assumptions.
          Use the passed type or decode it from the die.  */
@@ -8563,7 +8521,7 @@ new_symbol (struct die_info *die, struct
 	  add_symbol_to_list (sym, cu->list_in_scope);
 	  break;
 	case DW_TAG_enumerator:
-	  SYMBOL_LINKAGE_NAME (sym) = (char *) dwarf2_full_name (die, cu);
+	  SYMBOL_LINKAGE_NAME (sym) = (char *) dwarf2_name (die, cu);
 	  attr = dwarf2_attr (die, DW_AT_const_value, cu);
 	  if (attr)
 	    {
@@ -8600,8 +8558,7 @@ new_symbol (struct die_info *die, struct
       /* For the benefit of old versions of GCC, check for anonymous
 	 namespaces based on the demangled name.  */
       if (!processing_has_namespace_info
-	  && cu->language == language_cplus
-	  && dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu) != NULL)
+	  && cu->language == language_cplus)
 	cp_scan_for_anonymous_namespaces (sym);
     }
   return (sym);
@@ -8943,6 +8900,96 @@ determine_prefix (struct die_info *die, 
       }
 }
 
+/* Determines the prefix for a symbol's physname.  Unlike determine_prefix,
+   this method does not simply look at the DIE's immediate parent.
+   It will compute the symbol's physname by scanning through all parent
+   DIEs until it gets to the compilation unit's DIE.  */
+
+static char *
+physname_prefix (struct die_info *die, struct dwarf2_cu *cu)
+{
+  long length;
+  struct ui_file *buf;
+  struct die_info *d, *spec_die;
+  struct dwarf2_cu *spec_cu;
+  char *name;
+
+  /* Construct a stack containing all of the DIE's parents.  Caution
+     must be observed for dealing with DW_AT_specification. */
+  spec_cu = cu;
+  spec_die = die_specification (die, &spec_cu);
+  if (spec_die != NULL)
+    d = spec_die->parent;
+  else
+    d = die->parent;
+  while (d != NULL && d->tag != DW_TAG_compile_unit)
+    {
+      struct attribute *attr;
+
+      spec_die = die_specification (d, &spec_cu);
+      if (spec_die != NULL)
+	d = spec_die;
+
+      VEC_quick_push (die_info_p, die_list, d);
+      d = d->parent;
+    }
+
+  /* Now pop all the elements, printing their names as we go.  */
+  buf = mem_fileopen ();
+  while (!VEC_empty (die_info_p, die_list))
+    {
+      d = VEC_pop (die_info_p, die_list);
+      physname_prefix_1 (buf, d, cu);
+
+      if (!VEC_empty (die_info_p, die_list))
+	{
+	  if (cu->language == language_cplus)
+	    fputs_unfiltered ("::", buf);
+	  else
+	    fputs_unfiltered (".", buf);
+	}
+    }
+
+  name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack, &length);
+  ui_file_delete (buf);
+  return name;
+}
+
+static void
+physname_prefix_1 (struct ui_file *buf, struct die_info *die,
+		   struct dwarf2_cu *cu)
+{
+  const char *name = NULL;
+  gdb_assert (buf != NULL);
+
+  if (die != NULL)
+    {
+      switch (die->tag)
+	{
+	case DW_TAG_namespace:
+	  name = dwarf2_name (die, cu);
+	  if (name == NULL)
+	    name = "(anonymous namespace)";
+	  break;
+
+	case DW_TAG_class_type:
+	case DW_TAG_structure_type:
+	case DW_TAG_union_type:
+	case DW_TAG_enumeration_type:
+	case DW_TAG_interface_type:
+	case DW_TAG_subprogram:
+	  name = dwarf2_name (die, cu);
+	  break;
+
+	default:
+	  break;
+	}
+    }
+
+  if (name != NULL)
+    fputs_unfiltered (name, buf);
+}
+
 /* Return a newly-allocated string formed by concatenating PREFIX and
    SUFFIX with appropriate separator.  If PREFIX or SUFFIX is NULL or empty, then
    simply copy the SUFFIX or PREFIX, respectively.  If OBS is non-null,
@@ -8992,17 +9039,78 @@ sibling_die (struct die_info *die)
   return die->sibling;
 }
 
-/* Get linkage name of a die, return NULL if not found.  */
+/* Construct a physname for the given DIE in CU. */
 
 static char *
-dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
+dwarf2_physname (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
+  char *name;
+
+  name = dwarf2_name (die, cu);
+
+  /* These are the only languages we know how to qualify names in.  */
+  if (cu->language != language_cplus
+      && cu->language != language_java)
+    return name;
+
+  if (die_needs_namespace (die, cu))
+    {
+      long length;
+      char *prefix;
+      struct ui_file *buf;
+
+      prefix = physname_prefix (die, cu);
+      buf = mem_fileopen ();
+      if (*prefix != '\0')
+	{
+	  char *prefixed_name = typename_concat (NULL, prefix, name, cu);
+	  fputs_unfiltered (prefixed_name, buf);
+	  xfree (prefixed_name);
+	}
+      else
+	fputs_unfiltered (name ? name : "", buf);
+
+      /* For Java and C++ methods, append formal parameter type
+	 information. */
+      if ((cu->language == language_cplus || cu->language == language_java)
+	  && die->tag == DW_TAG_subprogram)
+	{
+	  struct type *type = read_type_die (die, cu);
 
-  attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
-  if (attr && DW_STRING (attr))
-    return DW_STRING (attr);
-  return dwarf2_name (die, cu);
+	  c_type_print_args (type, buf, 0, cu->language);
+
+	  if (cu->language == language_java)
+	    {
+	      /* For java, we must append the return type to method names. */
+	      if (die->tag == DW_TAG_subprogram)
+		java_print_type (TYPE_TARGET_TYPE (type), "", buf, 0, 0);
+	    }
+	  else if (cu->language == language_cplus)
+	    {
+	      /* c_type_print_args adds argument types, but it does
+		 not add any necessary "const". */
+	      if (TYPE_NFIELDS (type) > 0 && TYPE_FIELD_ARTIFICIAL (type, 0)
+		  && TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0))))
+		fputs_unfiltered (" const", buf);
+	    }
+	}
+
+      name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack,
+				   &length);
+      ui_file_delete (buf);
+
+      if (cu->language == language_cplus)
+	{
+	  char *cname
+	    = dwarf2_canonicalize_name (name, cu,
+					&cu->objfile->objfile_obstack);
+	  if (cname != NULL)
+	    name = cname;
+	}
+    }
+
+  return name;
 }
 
 /* Get name of a die, return NULL if not found.  */
@@ -11885,6 +11993,7 @@ void _initialize_dwarf2_read (void);
 void
 _initialize_dwarf2_read (void)
 {
+  die_list = VEC_alloc (die_info_p, 32);
   dwarf2_objfile_data_key
     = register_objfile_data_with_cleanup (NULL, dwarf2_per_objfile_free);
 
Index: gnu-v3-abi.c
===================================================================
RCS file: /cvs/src/src/gdb/gnu-v3-abi.c,v
retrieving revision 1.57
diff -u -p -r1.57 gnu-v3-abi.c
--- gnu-v3-abi.c	12 Nov 2009 19:47:25 -0000	1.57
+++ gnu-v3-abi.c	19 Nov 2009 23:53:58 -0000
@@ -26,6 +26,7 @@
 #include "demangle.h"
 #include "objfiles.h"
 #include "valprint.h"
+#include "c-lang.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
@@ -456,10 +457,8 @@ gnuv3_find_method_in (struct type *domai
 		      LONGEST adjustment)
 {
   int i;
-  const char *physname;
 
   /* Search this class first.  */
-  physname = NULL;
   if (adjustment == 0)
     {
       int len;
@@ -587,15 +586,24 @@ gnuv3_print_method_ptr (const gdb_byte *
 	{
 	  char *demangled_name = cplus_demangle (physname,
 						 DMGL_ANSI | DMGL_PARAMS);
-	  if (demangled_name != NULL)
+	  fprintf_filtered (stream, "&virtual ");
+	  if (demangled_name == NULL)
+	    fputs_filtered (physname, stream);
+	  else
 	    {
-	      fprintf_filtered (stream, "&virtual ");
 	      fputs_filtered (demangled_name, stream);
 	      xfree (demangled_name);
-	      return;
 	    }
+	  return;
 	}
     }
+  else if (ptr_value != 0)
+    {
+      /* Found a non-virtual function: print out the type.  */
+      fputs_filtered ("(", stream);
+      c_print_type (type, "", stream, -1, 0);
+      fputs_filtered (") ", stream);
+    }
 
   /* We didn't find it; print the raw data.  */
   if (vbit)
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.219
diff -u -p -r1.219 symtab.c
--- symtab.c	18 Nov 2009 16:28:42 -0000	1.219
+++ symtab.c	19 Nov 2009 23:54:00 -0000
@@ -42,6 +42,7 @@
 #include "ada-lang.h"
 #include "p-lang.h"
 #include "addrmap.h"
+#include "cp-support.h"
 
 #include "hashtab.h"
 
@@ -498,7 +495,7 @@ symbol_find_demangled_name (struct gener
       || gsymbol->language == language_auto)
     {
       demangled =
-        cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
+        cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
       if (demangled != NULL)
 	{
 	  gsymbol->language = language_cplus;
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.143
diff -u -p -r1.143 symtab.h
--- symtab.h	16 Nov 2009 18:40:23 -0000	1.143
+++ symtab.h	19 Nov 2009 23:54:01 -0000
@@ -172,9 +172,6 @@ extern CORE_ADDR symbol_overlayed_addres
 #define SYMBOL_SECTION(symbol)		(symbol)->ginfo.section
 #define SYMBOL_OBJ_SECTION(symbol)	(symbol)->ginfo.obj_section
 
-#define SYMBOL_CPLUS_DEMANGLED_NAME(symbol)	\
-  (symbol)->ginfo.language_specific.cplus_specific.demangled_name
-
 /* Initializes the language dependent portion of a symbol
    depending upon the language for the symbol. */
 #define SYMBOL_INIT_LANGUAGE_SPECIFIC(symbol,language) \
Index: typeprint.h
===================================================================
RCS file: /cvs/src/src/gdb/typeprint.h,v
retrieving revision 1.8
diff -u -p -r1.8 typeprint.h
--- typeprint.h	3 Jan 2009 05:57:53 -0000	1.8
+++ typeprint.h	19 Nov 2009 23:54:01 -0000
@@ -20,10 +20,13 @@
 #ifndef TYPEPRINT_H
 #define TYPEPRINT_H
 
+enum language;
 struct ui_file;
 
 void print_type_scalar (struct type * type, LONGEST, struct ui_file *);
 
 void c_type_print_varspec_suffix (struct type *, struct ui_file *, int,
 				  int, int);
+
+void c_type_print_args (struct type *, struct ui_file *, int, enum language);
 #endif
Index: ui-file.c
===================================================================
RCS file: /cvs/src/src/gdb/ui-file.c,v
retrieving revision 1.19
diff -u -p -r1.19 ui-file.c
--- ui-file.c	13 Nov 2009 22:54:42 -0000	1.19
+++ ui-file.c	19 Nov 2009 23:54:01 -0000
@@ -22,6 +22,7 @@
 
 #include "defs.h"
 #include "ui-file.h"
+#include "gdb_obstack.h"
 #include "gdb_string.h"
 #include "gdb_select.h"
 
@@ -264,7 +265,7 @@ set_ui_file_data (struct ui_file *file, 
 }
 
 /* ui_file utility function for converting a ``struct ui_file'' into
-   a memory buffer''. */
+   a memory buffer. */
 
 struct accumulated_ui_file
 {
@@ -298,6 +299,23 @@ ui_file_xstrdup (struct ui_file *file, l
     *length = acc.length;
   return acc.buffer;
 }
+
+static void
+do_ui_file_obsavestring (void *context, const char *buffer, long length)
+{
+  struct obstack *obstack = (struct obstack *) context;
+  obstack_grow (obstack, buffer, length);
+}
+
+char *
+ui_file_obsavestring (struct ui_file *file, struct obstack *obstack,
+		      long *length)
+{
+  ui_file_put (file, do_ui_file_obsavestring, obstack);
+  *length = obstack_object_size (obstack);
+  obstack_1grow (obstack, '\0');
+  return obstack_finish (obstack);
+}
 \f
 /* A pure memory based ``struct ui_file'' that can be used an output
    buffer. The buffers accumulated contents are available via
Index: ui-file.h
===================================================================
RCS file: /cvs/src/src/gdb/ui-file.h,v
retrieving revision 1.10
diff -u -p -r1.10 ui-file.h
--- ui-file.h	14 Aug 2009 00:32:32 -0000	1.10
+++ ui-file.h	19 Nov 2009 23:54:02 -0000
@@ -19,6 +19,7 @@
 #ifndef UI_FILE_H
 #define UI_FILE_H
 
+struct obstack;
 struct ui_file;
 
 /* Create a generic ui_file object with null methods. */
@@ -77,7 +78,10 @@ extern void ui_file_put (struct ui_file 
    minus that appended NUL. */
 extern char *ui_file_xstrdup (struct ui_file *file, long *length);
 
-
+/* Similar to ui_file_xstrdup, but return a new string allocated on
+   OBSTACK.  */
+extern char *ui_file_obsavestring (struct ui_file *file,
+				   struct obstack *obstack, long *length);
 
 extern long ui_file_read (struct ui_file *file, char *buf, long length_buf);
 
Index: utils.c
===================================================================
RCS file: /cvs/src/src/gdb/utils.c,v
retrieving revision 1.219
diff -u -p -r1.219 utils.c
--- utils.c	18 Aug 2009 16:17:16 -0000	1.219
+++ utils.c	19 Nov 2009 23:54:02 -0000
@@ -2610,7 +2610,10 @@ fprintf_symbol_filtered (struct ui_file 
    As an extra hack, string1=="FOO(ARGS)" matches string2=="FOO".
    This "feature" is useful when searching for matching C++ function names
    (such as if the user types 'break FOO', where FOO is a mangled C++
-   function). */
+   function).
+
+   As an extra-special hack, we do the same with ' ', so that
+   "FOO(ARGS) const" can match "FOO", too.  */
 
 int
 strcmp_iw (const char *string1, const char *string2)
@@ -2635,7 +2638,7 @@ strcmp_iw (const char *string1, const ch
 	  string2++;
 	}
     }
-  return (*string1 != '\0' && *string1 != '(') || (*string2 != '\0');
+  return (*string1 != ' ' && *string1 != '\0' && *string1 != '(') || (*string2 != '\0' && *string2 != '(');
 }
 
 /* This is like strcmp except that it ignores whitespace and treats
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.227
diff -u -p -r1.227 valops.c
--- valops.c	10 Nov 2009 22:17:58 -0000	1.227
+++ valops.c	19 Nov 2009 23:54:02 -0000
@@ -2071,12 +2071,25 @@ find_overload_match (struct type **arg_t
   if (method)
     {
       gdb_assert (obj);
+
+      /* OBJ may be a pointer value rather than the object itself.  */
+      obj = coerce_ref (obj);
+      while (TYPE_CODE (check_typedef (value_type (obj))) == TYPE_CODE_PTR)
+	obj = coerce_ref (value_ind (obj));
       obj_type_name = TYPE_NAME (value_type (obj));
-      /* Hack: evaluate_subexp_standard often passes in a pointer
-         value rather than the object itself, so try again.  */
-      if ((!obj_type_name || !*obj_type_name) 
-	  && (TYPE_CODE (value_type (obj)) == TYPE_CODE_PTR))
-	obj_type_name = TYPE_NAME (TYPE_TARGET_TYPE (value_type (obj)));
+
+      /* First check whether this is a data member, e.g. a pointer to
+	 a function.  */
+      if (TYPE_CODE (check_typedef (value_type (obj))) == TYPE_CODE_STRUCT)
+	{
+	  *valp = search_struct_field (name, obj, 0,
+				       check_typedef (value_type (obj)), 0);
+	  if (*valp)
+	    {
+	      *staticp = 1;
+	      return 0;
+	    }
+	}
 
       fns_ptr = value_find_oload_method_list (&temp, name, 
 					      0, &num_fns, 
@@ -2096,16 +2109,29 @@ find_overload_match (struct type **arg_t
     }
   else
     {
-      const char *qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym);
+      const char *qualified_name = SYMBOL_NATURAL_NAME (fsym);
+
+      /* If we have a function with a C++ name, try to extract just
+	 the function part.  Do not try this for non-functions (e.g.
+	 function pointers).  */
+      if (qualified_name
+	  && TYPE_CODE (check_typedef (SYMBOL_TYPE (fsym))) == TYPE_CODE_FUNC)
+	{
+	  func_name = cp_func_name (qualified_name);
+
+	  /* If cp_func_name did not remove anything, the name of the
+	     symbol did not include scope or argument types - it was
+	     probably a C-style function.  */
+	  if (func_name && strcmp (func_name, qualified_name) == 0)
+	    {
+	      xfree (func_name);
+	      func_name = NULL;
+	    }
+	}
 
-      /* If we have a C++ name, try to extract just the function
-	 part.  */
-      if (qualified_name)
-	func_name = cp_func_name (qualified_name);
-
-      /* If there was no C++ name, this must be a C-style function.
-	 Just return the same symbol.  Do the same if cp_func_name
-	 fails for some reason.  */
+      /* If there was no C++ name, this must be a C-style function or
+	 not a function at all.  Just return the same symbol.  Do the
+	 same if cp_func_name fails for some reason.  */
       if (func_name == NULL)
         {
 	  *symp = fsym;

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-20 21:20 [RFA 2/4] dwarf2_physname Keith Seitz
@ 2009-11-20 22:10 ` Daniel Jacobowitz
  2009-11-21  0:04   ` Tom Tromey
                     ` (2 more replies)
  2009-11-23  7:31 ` André Pönitz
  2009-11-24 22:11 ` Joel Brobecker
  2 siblings, 3 replies; 50+ messages in thread
From: Daniel Jacobowitz @ 2009-11-20 22:10 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Fri, Nov 20, 2009 at 01:19:35PM -0800, Keith Seitz wrote:
> The attached patch is the real "meat and potatoes" of the thing. It
> includes much of the earlier patches that I posted on August 31,
> except that this leaves out none of the details.

Actually reviewing this is going to take more time than I have today,
but the first thing I wanted to do was drop it into my RealView test
harness and see what happened.  Across three RealView multilibs and
two ARM GCC multilibs:

495 FAIL -> PASS
75 New FAIL
130 PASS -> FAIL
87 Removed FAIL
3 Removed KPASS
6 UNRESOLVED -> PASS

Pretty good.  A few of the failures were related to another patch I
had on my last test run which is still pending.  Some of the
PASS -> FAIL are with GCC though.

I am generally opposed to committing known regressions.  If there are
supporting patches we need to get in first, let's do that; if there
are tests we decide to break, let's XFAIL or KFAIL them.  That's the
only way we can make the testsuite more useful.

The related regressions, just with arm-none-eabi GCC and the default
multilib:

PASS -> FAIL: default/gdb.sum:gdb.base/code-expr.exp: (@code signed long)
PASS -> FAIL: default/gdb.sum:gdb.base/code-expr.exp: (@data signed long)
PASS -> FAIL: default/gdb.sum:gdb.base/code-expr.exp: (signed long @code)
PASS -> FAIL: default/gdb.sum:gdb.base/code-expr.exp: (signed long @data)
PASS -> FAIL: default/gdb.sum:gdb.base/cvexpr.exp: (const signed long)
PASS -> FAIL: default/gdb.sum:gdb.base/cvexpr.exp: (signed long const)
PASS -> FAIL: default/gdb.sum:gdb.base/cvexpr.exp: (signed long volatile)
PASS -> FAIL: default/gdb.sum:gdb.base/cvexpr.exp: (volatile signed long)
PASS -> FAIL: default/gdb.sum:gdb.cp/exception.exp: backtrace after first catch
PASS -> FAIL: default/gdb.sum:gdb.cp/exception.exp: backtrace after first throw
PASS -> FAIL: default/gdb.sum:gdb.cp/exception.exp: backtrace after second catch
PASS -> FAIL: default/gdb.sum:gdb.cp/exception.exp: backtrace after second throw
PASS -> FAIL: default/gdb.sum:gdb.cp/namespace.exp: print X
PASS -> FAIL: default/gdb.sum:gdb.cp/namespace.exp: print cX

I'm going to skip the RealView regressions; those I'm willing to
handle in followups.  Most template tests still fail with RealView.
Some tests from namespace.exp improved, others regressed.

Any idea what the above failures might be?  I can send you logs
offlist, they're large.

> Some warnings are in order. First, this is probably going to really
> slow down large C++ applications, because we no longer use
> DW_AT_MIPS_linkage_name as generated from the compiler. We
> essentially build this name during DIE reading.

We need to quantify the impact on a couple of C++ code bases, I think.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-20 22:10 ` Daniel Jacobowitz
@ 2009-11-21  0:04   ` Tom Tromey
  2009-11-21  3:46     ` Frank Ch. Eigler
  2009-11-23 16:52   ` Keith Seitz
  2009-12-08 19:47   ` Keith Seitz
  2 siblings, 1 reply; 50+ messages in thread
From: Tom Tromey @ 2009-11-21  0:04 UTC (permalink / raw)
  To: gdb-patches

>>>>> "Daniel" == Daniel Jacobowitz <drow@false.org> writes:

Keith> Some warnings are in order. First, this is probably going to really
Keith> slow down large C++ applications, because we no longer use
Keith> DW_AT_MIPS_linkage_name as generated from the compiler. We
Keith> essentially build this name during DIE reading.

Daniel> We need to quantify the impact on a couple of C++ code bases, I think.

I think it is worth noting that this problem should be mostly solved by
some work I'm in the middle of.  This work involves making psymtabs
optional (it is left up to the debuginfo reader to decide), and then
making use of various DWARF indices (we have a new section but debate
about this is ongoing) to speed up the DWARF case.  The upshot of this
is that we'll generally only read CUs on demand, and we won't do the
initial scan we currently do for psymtabs.

This work won't help with existing code, though, because it relies on
indices we don't have access to (even if we use the standard DWARF ones,
those are unusable with older versions of GCC).

If you're interested in this, it is on archer-tromey-optional-psymtab.
You'll also want the compiler and readelf patches from:

    http://gcc.gnu.org/bugzilla/show_bug.cgi?id=41130

This is a work in progress.

Tom


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-21  0:04   ` Tom Tromey
@ 2009-11-21  3:46     ` Frank Ch. Eigler
  2009-11-23 18:06       ` Tom Tromey
  0 siblings, 1 reply; 50+ messages in thread
From: Frank Ch. Eigler @ 2009-11-21  3:46 UTC (permalink / raw)
  To: tromey; +Cc: gdb-patches


Tom Tromey <tromey@redhat.com> writes:

> [...]  This work won't help with existing code, though, because it
> relies on indices we don't have access to (even if we use the
> standard DWARF ones, those are unusable with older versions of
> GCC). [...]

Could gdb generate those indices for executables without them,
and save them someplace (perhaps even within the executable)?

- FChE


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-20 21:20 [RFA 2/4] dwarf2_physname Keith Seitz
  2009-11-20 22:10 ` Daniel Jacobowitz
@ 2009-11-23  7:31 ` André Pönitz
  2009-11-23 16:57   ` Keith Seitz
  2009-11-23 17:15   ` Tom Tromey
  2009-11-24 22:11 ` Joel Brobecker
  2 siblings, 2 replies; 50+ messages in thread
From: André Pönitz @ 2009-11-23  7:31 UTC (permalink / raw)
  To: gdb-patches

On Friday 20 November 2009 22:19:35 Keith Seitz wrote:
> [...] Some warnings are in order. First, this is probably going to really slow 
> down large C++ applications, because we no longer use 
> DW_AT_MIPS_linkage_name as generated from the compiler. We essentially 
> build this name during DIE reading. [...]
> With those caveats out of the way, I will say that I understand there 
> are some controversial changes in here: it is a pretty big paradigm 
> shift for the dwarf reader. Nonetheless, the benefits outweigh the 
> performance degradation (for C++ ONLY) and the minor java regression. 
> IMO, the elimination of single-quoting for C++ expressions alone is 
> worth it.
> 
> Questions/comments/concerns?

I am really worried about the performance degradation you expect.

How bad will that be?

Medium to large sized C++ applications is basically "all I have", and speed 
is already by now the biggest issue I have with gdb. [1]

If the deal is "correct but slow" vs "flaky but faster" I surely prefer the 
"flaky but fast" side. I have encountered quite a few issues with C++ in 
gdb, so yes, that's not nice. But usually one can work around somehow on 
the user side. Raw speed on the other hand is nothing the user can improve.

Andre'

[1] Actually "the biggest issue that is left": Python scripting turned out
to be a panacea for basically everything else. Thanks to everybody involved.


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-20 22:10 ` Daniel Jacobowitz
  2009-11-21  0:04   ` Tom Tromey
@ 2009-11-23 16:52   ` Keith Seitz
  2009-11-23 17:08     ` Daniel Jacobowitz
  2009-12-08 19:47   ` Keith Seitz
  2 siblings, 1 reply; 50+ messages in thread
From: Keith Seitz @ 2009-11-23 16:52 UTC (permalink / raw)
  To: gdb-patches

On 11/20/2009 02:09 PM, Daniel Jacobowitz wrote:

> I am generally opposed to committing known regressions.  If there are
> supporting patches we need to get in first, let's do that; if there
> are tests we decide to break, let's XFAIL or KFAIL them.  That's the
> only way we can make the testsuite more useful.

Sami has a follow-on patch that he could submit to fix all of these 
tests (they all pass on archer-keiths-expr-cumulative). Perhaps it would 
be acceptable for Sami to submit that patchset when/if this patch is 
accepted? [His patches rely on this patchset.]

> The related regressions, just with arm-none-eabi GCC and the default
> multilib:

I'm building an arm-elf toolchain now, and I will run it through testing.

> PASS ->  FAIL: default/gdb.sum:gdb.base/code-expr.exp: (@code signed long)
> PASS ->  FAIL: default/gdb.sum:gdb.base/code-expr.exp: (@data signed long)
> PASS ->  FAIL: default/gdb.sum:gdb.base/code-expr.exp: (signed long @code)
> PASS ->  FAIL: default/gdb.sum:gdb.base/code-expr.exp: (signed long @data)
> PASS ->  FAIL: default/gdb.sum:gdb.base/cvexpr.exp: (const signed long)
> PASS ->  FAIL: default/gdb.sum:gdb.base/cvexpr.exp: (signed long const)
> PASS ->  FAIL: default/gdb.sum:gdb.base/cvexpr.exp: (signed long volatile)
> PASS ->  FAIL: default/gdb.sum:gdb.base/cvexpr.exp: (volatile signed long)
> PASS ->  FAIL: default/gdb.sum:gdb.cp/exception.exp: backtrace after first catch
> PASS ->  FAIL: default/gdb.sum:gdb.cp/exception.exp: backtrace after first throw
> PASS ->  FAIL: default/gdb.sum:gdb.cp/exception.exp: backtrace after second catch
> PASS ->  FAIL: default/gdb.sum:gdb.cp/exception.exp: backtrace after second throw

Don't know about the above failures just yet, but...

> PASS ->  FAIL: default/gdb.sum:gdb.cp/namespace.exp: print X
> PASS ->  FAIL: default/gdb.sum:gdb.cp/namespace.exp: print cX

These are the two regressions that are addressed by Sami's (unsubmitted) 
patch.

> I'm going to skip the RealView regressions; those I'm willing to
> handle in followups.  Most template tests still fail with RealView.
> Some tests from namespace.exp improved, others regressed.

I think we discussed it earlier, but to be clear: RealView will 
demonstrate problems with templates, since it relies on 
DW_TAG_template_{value,type}_parameter, which gdb does not yet 
understand. [I've played with it a bit, but value parameters are *tough* 
on dwarf2_physname.]

> Any idea what the above failures might be?  I can send you logs
> offlist, they're large.

Yes, send the to me at this account.

>> Some warnings are in order. First, this is probably going to really
>> slow down large C++ applications, because we no longer use
>> DW_AT_MIPS_linkage_name as generated from the compiler. We
>> essentially build this name during DIE reading.
>
> We need to quantify the impact on a couple of C++ code bases, I think.

Indeed. I ran some contrived speed tests a long time ago, but I never 
really felt that the adequately represented reality. [I believe they 
were the equivalent of running "file XXX; info func".]

We did show a slowdown on OO.o, but I don't recall the exact numbers 
right now.

If we can define a suitable test procedure for this, I would be happy to 
produce some comparisons.

Keith


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-23  7:31 ` André Pönitz
@ 2009-11-23 16:57   ` Keith Seitz
  2009-11-23 17:20     ` Tom Tromey
  2009-11-24  7:22     ` André Pönitz
  2009-11-23 17:15   ` Tom Tromey
  1 sibling, 2 replies; 50+ messages in thread
From: Keith Seitz @ 2009-11-23 16:57 UTC (permalink / raw)
  To: André Pönitz; +Cc: gdb-patches

On 11/22/2009 11:26 PM, André Pönitz wrote:

> I am really worried about the performance degradation you expect.
>
> How bad will that be?

If we can define a suitable metric, I would be happy to perform any 
testing/comparisons necessary.

> If the deal is "correct but slow" vs "flaky but faster" I surely prefer the
> "flaky but fast" side. I have encountered quite a few issues with C++ in
> gdb, so yes, that's not nice. But usually one can work around somehow on
> the user side. Raw speed on the other hand is nothing the user can improve.

I'm more of a "correct over speed" guy myself, but your concern is 
noted. Maintainers will have to weigh this matter when more information 
about the impact is known.

Like I said: If anyone can define for me a suitable test(s), I would be 
happy to do whatever necessary to quantify this.

Keith


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-23 16:52   ` Keith Seitz
@ 2009-11-23 17:08     ` Daniel Jacobowitz
  2009-11-24 19:20       ` Sami Wagiaalla
  0 siblings, 1 reply; 50+ messages in thread
From: Daniel Jacobowitz @ 2009-11-23 17:08 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Mon, Nov 23, 2009 at 08:51:16AM -0800, Keith Seitz wrote:
> On 11/20/2009 02:09 PM, Daniel Jacobowitz wrote:
> 
> >I am generally opposed to committing known regressions.  If there are
> >supporting patches we need to get in first, let's do that; if there
> >are tests we decide to break, let's XFAIL or KFAIL them.  That's the
> >only way we can make the testsuite more useful.
> 
> Sami has a follow-on patch that he could submit to fix all of these
> tests (they all pass on archer-keiths-expr-cumulative). Perhaps it
> would be acceptable for Sami to submit that patchset when/if this
> patch is accepted? [His patches rely on this patchset.]

If it applies on top of this, could he post it now?  Then we can treat
them as a unit for review and testing purposes.

> >The related regressions, just with arm-none-eabi GCC and the default
> >multilib:
> 
> I'm building an arm-elf toolchain now, and I will run it through testing.

Might need to be arm-eabi for some cases, I'm not sure.  I haven't
tried arm-elf in a while.

> >I'm going to skip the RealView regressions; those I'm willing to
> >handle in followups.  Most template tests still fail with RealView.
> >Some tests from namespace.exp improved, others regressed.
> 
> I think we discussed it earlier, but to be clear: RealView will
> demonstrate problems with templates, since it relies on
> DW_TAG_template_{value,type}_parameter, which gdb does not yet
> understand. [I've played with it a bit, but value parameters are
> *tough* on dwarf2_physname.]

Right.  I figured this out after the fact.

Did I send you my local implementation of
DW_TAG_template_value_parameter?  It's... not pretty.

> >Any idea what the above failures might be?  I can send you logs
> >offlist, they're large.
> 
> Yes, send the to me at this account.

Will do.  Rerunning with cpexprs.exp included this time.

> If we can define a suitable test procedure for this, I would be happy
> to produce some comparisons.

I'd like to leave Tom's work - exciting as it is - out of the
discussion for the moment.  I suggest picking a couple of C++
programs, preferably with different degrees of template-ness.

The interesting numbers are, IMO:

* psymtab creation ("time gdb -batch foo").
* full symbol creation ("time gdb -batch -readnow foo").
* some vaguely realistic operation, e.g. set a breakpoint near the
start of the application and run it through loading shared libraries
and print a backtrace.

-readnow numbers are interesting, but not vital.  That is, a big
slowdown there is not necessarily a big problem.

Thoughts?

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-23  7:31 ` André Pönitz
  2009-11-23 16:57   ` Keith Seitz
@ 2009-11-23 17:15   ` Tom Tromey
  1 sibling, 0 replies; 50+ messages in thread
From: Tom Tromey @ 2009-11-23 17:15 UTC (permalink / raw)
  To: André Pönitz; +Cc: gdb-patches

>>>>> "André" == André Pönitz <andre.poenitz@nokia.com> writes:

André> Medium to large sized C++ applications is basically "all I have",
André> and speed is already by now the biggest issue I have with
André> gdb. [1]

I'm interested to know what operations specifically are too slow.

Tom


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-23 16:57   ` Keith Seitz
@ 2009-11-23 17:20     ` Tom Tromey
  2009-11-24  7:22     ` André Pönitz
  1 sibling, 0 replies; 50+ messages in thread
From: Tom Tromey @ 2009-11-23 17:20 UTC (permalink / raw)
  To: Keith Seitz; +Cc: André Pönitz, gdb-patches

>>>>> "Keith" == Keith Seitz <keiths@redhat.com> writes:

Keith> Like I said: If anyone can define for me a suitable test(s), I would
Keith> be happy to do whatever necessary to quantify this.

My typical tests for performance with C++ are to start OO.o writer, then
time "attach" or "bt" or "thread apply all bt full", depending on what I
am interested in measuring.

I picked this just because it is big, written in C++, and uses a lot of
shared libraries.

FWIW I believe we can have both correctness and good performance in this
area.

Tom


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-21  3:46     ` Frank Ch. Eigler
@ 2009-11-23 18:06       ` Tom Tromey
  2009-11-23 19:00         ` Daniel Jacobowitz
  0 siblings, 1 reply; 50+ messages in thread
From: Tom Tromey @ 2009-11-23 18:06 UTC (permalink / raw)
  To: Frank Ch. Eigler; +Cc: gdb-patches

>>>>> "Frank" == Frank Ch Eigler <fche@redhat.com> writes:

>> [...]  This work won't help with existing code, though, because it
>> relies on indices we don't have access to (even if we use the
>> standard DWARF ones, those are unusable with older versions of
>> GCC). [...]

Frank> Could gdb generate those indices for executables without them,
Frank> and save them someplace (perhaps even within the executable)?

It would be possible.  I'm not sure I would want gdb to do this, though.
A separate program to do it seems more appropriate.

Tom


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-23 18:06       ` Tom Tromey
@ 2009-11-23 19:00         ` Daniel Jacobowitz
  0 siblings, 0 replies; 50+ messages in thread
From: Daniel Jacobowitz @ 2009-11-23 19:00 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Frank Ch. Eigler, gdb-patches

On Mon, Nov 23, 2009 at 11:05:00AM -0700, Tom Tromey wrote:
> >>>>> "Frank" == Frank Ch Eigler <fche@redhat.com> writes:
> 
> >> [...]  This work won't help with existing code, though, because it
> >> relies on indices we don't have access to (even if we use the
> >> standard DWARF ones, those are unusable with older versions of
> >> GCC). [...]
> 
> Frank> Could gdb generate those indices for executables without them,
> Frank> and save them someplace (perhaps even within the executable)?
> 
> It would be possible.  I'm not sure I would want gdb to do this, though.
> A separate program to do it seems more appropriate.

I think both options have value - this seems like a good evolution of
the previous mmalloc approach to speeding up startup.  Stick a cache
in $HOME...

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-23 16:57   ` Keith Seitz
  2009-11-23 17:20     ` Tom Tromey
@ 2009-11-24  7:22     ` André Pönitz
  2009-11-24 22:54       ` Tom Tromey
  1 sibling, 1 reply; 50+ messages in thread
From: André Pönitz @ 2009-11-24  7:22 UTC (permalink / raw)
  To: gdb-patches

On Monday 23 November 2009 17:56:10 Keith Seitz wrote:
> On 11/22/2009 11:26 PM, André Pönitz wrote:
> 
> > I am really worried about the performance degradation you expect.
> >
> > How bad will that be?
> 
> If we can define a suitable metric, I would be happy to perform any 
> testing/comparisons necessary.
> 
> > If the deal is "correct but slow" vs "flaky but faster" I surely prefer the
> > "flaky but fast" side. I have encountered quite a few issues with C++ in
> > gdb, so yes, that's not nice. But usually one can work around somehow on
> > the user side. Raw speed on the other hand is nothing the user can improve.
> 
> I'm more of a "correct over speed" guy myself, but your concern is 
> noted. Maintainers will have to weigh this matter when more information 
> about the impact is known.
> 
> Like I said: If anyone can define for me a suitable test(s), I would be 
> happy to do whatever necessary to quantify this.

I am in the same camp in general, too, but in this particular case
the "user experience" is already stretched to a degree that people
start pointing fingers ;-}

I guess it's hard to come up with a benchmark that everybody 
would consider authoritive. I could run a few tests for scenarios
I am interested in, though. Am I right in assuming that I could just
pull one of the archer archer-keiths-* branches? Would that be
archer-keiths-linkage_name-redux?

Andre'


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-23 17:08     ` Daniel Jacobowitz
@ 2009-11-24 19:20       ` Sami Wagiaalla
  2010-01-27 17:10         ` Sami Wagiaalla
  0 siblings, 1 reply; 50+ messages in thread
From: Sami Wagiaalla @ 2009-11-24 19:20 UTC (permalink / raw)
  To: gdb-patches

On 11/23/2009 12:07 PM, Daniel Jacobowitz wrote:
> On Mon, Nov 23, 2009 at 08:51:16AM -0800, Keith Seitz wrote:
>> On 11/20/2009 02:09 PM, Daniel Jacobowitz wrote:
>>
>>> I am generally opposed to committing known regressions.  If there are
>>> supporting patches we need to get in first, let's do that; if there
>>> are tests we decide to break, let's XFAIL or KFAIL them.  That's the
>>> only way we can make the testsuite more useful.
>>
>> Sami has a follow-on patch that he could submit to fix all of these
>> tests (they all pass on archer-keiths-expr-cumulative). Perhaps it
>> would be acceptable for Sami to submit that patchset when/if this
>> patch is accepted? [His patches rely on this patchset.]
>
> If it applies on top of this, could he post it now?  Then we can treat
> them as a unit for review and testing purposes.
>

I looked into this. It turns out that this is fixed by the patches 
posted on the thread rooted at this message
http://sourceware.org/ml/gdb-patches/2009-07/msg00305.html

Applying these patches prior to applying Keith's fixes the namespace.exp 
issues.

Note: parts of keiths patch to do with removing references to linkage 
name from cp-support, cp-namespace.c, valops.c give rise to conflicts so 
I just remove those manually.

Sami


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-20 21:20 [RFA 2/4] dwarf2_physname Keith Seitz
  2009-11-20 22:10 ` Daniel Jacobowitz
  2009-11-23  7:31 ` André Pönitz
@ 2009-11-24 22:11 ` Joel Brobecker
  2 siblings, 0 replies; 50+ messages in thread
From: Joel Brobecker @ 2009-11-24 22:11 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

>         (read_partial_die): Ignore DW_AT_MIPS_linkage_name for all
>         languages except Ada.

More info on this. After asking the compiler guys, it turns out that
GCC generates DIEs with a DW_AT_MIPS_linkage_name attribute when
an entity has a different linkage name from the mangled name (this
happens when a pragma Export is used to force the linkage name of
an entity). For instance:

    package P is
    
       Myconst : Integer := 1234;
       pragma Export (C, Myconst, "hello");
    
    end P;

The compiler generates:

        .uleb128 0x2    # (DIE (0x25) DW_TAG_variable)
        .long   .LASF3  # DW_AT_name: "p__myconst"
        .byte   0x1     # DW_AT_decl_file (p.ads)
        .byte   0x3     # DW_AT_decl_line
        .long   .LASF4  # DW_AT_MIPS_linkage_name: "hello"

Now that I have been reminded of this, I now remember that we have
an open enhancement request to be able to use either the natural
name or the linkage name in order to specify our entity.  In other
words, users want to be able to do either of:

        (gdb) print p.myconst
        (gdb) print hello

Right now, we only allow the latter.  Honestly, I strongly suspect
that this is accidental due to use prefering the DW_AT_MIPS_linkage_name
attribute over the DW_AT_name, but ``I wasn't there''.

Going back to the enhancement request, the way we were hoping to be
able to deal with that was to take advantage of the two names being
provided for our DIE, so we can't really think of removing the handling
of this attribute entirely without thinking about a different approach
first. The approach taken here of conditionalizing this to the CU language
against Ada is fine as far as I am concerned - I'll concede that it's
a little ugly.

In terms of how I'm planning to implement the enhancement, I actually
haven't thought much about it. If Ada was able to store both natural
and linkage name at the same time (instead of computing the natural
name on-demand), it'd probably be working to just compute the natural
name based on the DW_AT_name attribute while using the DW_AT_MIPS_linkage_name
for the linkage name...

I would like Ada to do the same as other projects, but it's not necessarily
straightforward. In order to spend the memory to store the natural name,
I need to save some memory elsewhere (some of our customers have projects
that cause GDB to use up as much memory as allowed by the system!).
Tom's work might allow us that saving, but I need to find the time to
investigate this first, although one of these customers is on a stabs
platform, so it might not help us there...

To be continued...

-- 
Joel


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-24  7:22     ` André Pönitz
@ 2009-11-24 22:54       ` Tom Tromey
  2009-11-25  9:16         ` André Pönitz
  0 siblings, 1 reply; 50+ messages in thread
From: Tom Tromey @ 2009-11-24 22:54 UTC (permalink / raw)
  To: André Pönitz; +Cc: gdb-patches

>>>>> "André" == André Pönitz <andre.poenitz@nokia.com> writes:

André> I guess it's hard to come up with a benchmark that everybody 
André> would consider authoritive. I could run a few tests for scenarios
André> I am interested in, though. Am I right in assuming that I could just
André> pull one of the archer archer-keiths-* branches? Would that be
André> archer-keiths-linkage_name-redux?

You want archer-keiths-expr-cumulative, that has these patches, but also
some other C++ expression fixes.

Tom


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-24 22:54       ` Tom Tromey
@ 2009-11-25  9:16         ` André Pönitz
  2009-11-25 18:14           ` Tom Tromey
  0 siblings, 1 reply; 50+ messages in thread
From: André Pönitz @ 2009-11-25  9:16 UTC (permalink / raw)
  To: gdb-patches; +Cc: Poenitz Andre (Nokia-D-Qt/Berlin)

On Tuesday 24 November 2009 23:54:06 Tom Tromey wrote:
> >>>>> "André" == André Pönitz <andre.poenitz@nokia.com> writes:
> 
> André> I guess it's hard to come up with a benchmark that everybody 
> André> would consider authoritive. I could run a few tests for scenarios
> André> I am interested in, though. Am I right in assuming that I could just
> André> pull one of the archer archer-keiths-* branches? Would that be
> André> archer-keiths-linkage_name-redux?
> 
> You want archer-keiths-expr-cumulative, that has these patches, but also
> some other C++ expression fixes.

Thanks.

Now the results of a highly unscientific approach at measuring "time"

# Attach to a running instance of Qt Creator using 
# time $1 -batch -pid $creatorpid -ex 'set confirm off' -ex q

# gdb 6.8 from Ubuntu 9.04 (optimized build)
real    0m9.508s user    0m8.653s sys     0m0.852s
real    0m9.607s user    0m8.585s sys     0m0.860s
real    0m9.726s user    0m8.677s sys     0m0.912s
real    0m9.747s user    0m8.697s sys     0m0.824s


# archer-tromey-python (debug version)
real    0m10.474s user     0m9.933s sys     0m0.520s
real    0m10.600s user     0m9.889s sys     0m0.472s
real    0m10.621s user     0m9.977s sys     0m0.484s
real    0m10.894s user    0m10.197s sys     0m0.544s

# archer-keiths-expr-cumulative (debug version)
real    0m11.410s user    0m10.741s sys     0m0.608s 
real    0m11.431s user    0m10.781s sys     0m0.636s 
real    0m11.519s user    0m10.865s sys     0m0.544s
real    0m11.540s user    0m10.809s sys     0m0.508s 

# archer-tromey-optional-psymtab (debug version)
real     0m8.687s user    0m7.772s sys     0m0.904s
real     0m8.687s user    0m7.816s sys     0m0.852s
real     0m8.823s user    0m7.828s sys     0m0.932s
real     0m9.050s user    0m7.936s sys     0m0.916s



# Attach to small program using QtCore and QtGui and run 'info types'
# time $1 -batch -pid $creatorpid -ex 'set confirm off' -ex 'set pagination off' -ex 'info types' -ex q

# gdb 6.8 from Ubuntu 9.04 (optimized build)
real    0m6.564s user    0m1.984s sys     0m0.252s
real    0m6.625s user    0m2.016s sys     0m0.256s
real    0m6.797s user    0m2.108s sys     0m0.268s

# archer-tromey-python (debug version)
real    0m5.180s user    0m1.784s sys     0m0.220s
real    0m5.237s user    0m1.832s sys     0m0.168s
real    0m5.165s user    0m1.764s sys     0m0.196s
real    0m5.187s user    0m1.832s sys     0m0.136s

# archer-keiths-expr-cumulative (debug version)
real    0m8.594s user    0m5.180s sys     0m0.264s
real    0m8.631s user    0m5.140s sys     0m0.252s
real    0m8.641s user    0m5.164s sys     0m0.272s
real    0m8.738s user    0m5.084s sys     0m0.320s

# archer-tromey-optional-psymtab (debug version)
real    0m5.085s user    0m1.592s sys     0m0.236s
real    0m5.101s user    0m1.592s sys     0m0.188s
real    0m5.091s user    0m1.656s sys     0m0.204s
real    0m5.080s user    0m1.552s sys     0m0.236s


Each scenario was run five times, I dropped the worst result from each,
so this is basically 'warm cache'. 

I understand that I should have better used optimized builds
(I can re-do the test if needed) but I guess the picture is clear.

Looking at the 'user' colums:

Block 'attach':

expr-cumulativ loses ~10% against tromey-python (which is, 
as I understand, unrelated to 'type stuff'). optional-psymtab 
on the other hand shows a nice ~20% improvement.

Block 'ptype':

expr-cumulativ loses  ~280% (!) against tromey-python, whereas 
optional-psymtab gains >~10%

If someone feels like I should use other build options or use other
commands for the timing, please say so.

Andre'


PS: I could not sensibly run 'info ptype' in the gdb attached to the
Qt Creator as gdb was taking more than 1.8 GB and I have only 2 GB
on my desktop.


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-25  9:16         ` André Pönitz
@ 2009-11-25 18:14           ` Tom Tromey
  0 siblings, 0 replies; 50+ messages in thread
From: Tom Tromey @ 2009-11-25 18:14 UTC (permalink / raw)
  To: André Pönitz; +Cc: gdb-patches

>>>>> "André" == André Pönitz <andre.poenitz@nokia.com> writes:

André> Now the results of a highly unscientific approach at measuring "time"

FWIW, I do this sort of timing too, I think it is pretty reasonable
provided that there isn't much background noise on the system.

André> # gdb 6.8 from Ubuntu 9.04 (optimized build)

GDB 7.0 as a baseline would be more interesting.  It may be a little
slower than 6.8 due to the C++ name canonicalization.  If so, using 6.8
as the baseline would make Keith's patch seem slower than it is.

André> Block 'ptype':
André> expr-cumulativ loses  ~280% (!) against tromey-python

I'm surprised by the archer-tromey-python result, I have no reason to
believe it should be faster than anything else.

André> [...], whereas 
André> optional-psymtab gains >~10%

FWIW that number is really the same as the delayed-symfile number,
because optional-psymtab only takes the fastest path if you built with a
modified GCC, to get the DWARF index.

Here are some numbers showing the speedup on a smallish (about 80 KLOC)
C++ program if you build it the right way:

CVS HEAD		1.83user 0.04system 0:02.06elapsed
delayed-symfile		1.30user 0.05system 0:01.50elapsed
optional-psymtab	0.43user 0.04system 0:00.51elapsed

I haven't tried it on my big test cases yet.

Tom


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-20 22:10 ` Daniel Jacobowitz
  2009-11-21  0:04   ` Tom Tromey
  2009-11-23 16:52   ` Keith Seitz
@ 2009-12-08 19:47   ` Keith Seitz
  2009-12-14 19:33     ` Keith Seitz
  2 siblings, 1 reply; 50+ messages in thread
From: Keith Seitz @ 2009-12-08 19:47 UTC (permalink / raw)
  To: gdb-patches

I apologize for the delay... It's been a week of holidays and debugging...

On 11/20/2009 02:09 PM, Daniel Jacobowitz wrote:
> The related regressions, just with arm-none-eabi GCC and the default
> multilib:
>
> PASS ->  FAIL: default/gdb.sum:gdb.base/code-expr.exp: (@code signed long)
> PASS ->  FAIL: default/gdb.sum:gdb.base/code-expr.exp: (@data signed long)
> PASS ->  FAIL: default/gdb.sum:gdb.base/code-expr.exp: (signed long @code)
> PASS ->  FAIL: default/gdb.sum:gdb.base/code-expr.exp: (signed long @data)
> PASS ->  FAIL: default/gdb.sum:gdb.base/cvexpr.exp: (const signed long)
> PASS ->  FAIL: default/gdb.sum:gdb.base/cvexpr.exp: (signed long const)
> PASS ->  FAIL: default/gdb.sum:gdb.base/cvexpr.exp: (signed long volatile)
> PASS ->  FAIL: default/gdb.sum:gdb.base/cvexpr.exp: (volatile signed long)

I've tracked this down to a misfeature I introduced to strcmp_iw to deal 
with "const" and "volatile". I've removed that, since I don't think that 
is the proper way to do this anymore. These tests now all pass. [I am 
also testing arm-eabi with the default multilib on the simulator.]

> PASS ->  FAIL: default/gdb.sum:gdb.cp/exception.exp: backtrace after first catch
> PASS ->  FAIL: default/gdb.sum:gdb.cp/exception.exp: backtrace after first throw
> PASS ->  FAIL: default/gdb.sum:gdb.cp/exception.exp: backtrace after second catch
> PASS ->  FAIL: default/gdb.sum:gdb.cp/exception.exp: backtrace after second throw

These are failing because the fully qualified name of 
"__cxxabiv1::__cxa_throw" is being shown in the backtraces instead of 
just "__cxa_throw".

> PASS ->  FAIL: default/gdb.sum:gdb.cp/namespace.exp: print X
> PASS ->  FAIL: default/gdb.sum:gdb.cp/namespace.exp: print cX

I think we've already established that these are fixed by Sami's 
outstanding patch (under review).

>> Some warnings are in order. First, this is probably going to really
>> slow down large C++ applications, because we no longer use
>> DW_AT_MIPS_linkage_name as generated from the compiler. We
>> essentially build this name during DIE reading.
>
> We need to quantify the impact on a couple of C++ code bases, I think.

Yeah, this is *really* bad. Really, really bad. But this was just a an 
attempt at "making it work." Now comes the "make it faster" part. I have 
a few ideas about redundant calls and whatnot, but it will undoubtedly 
take some real effort and refactoring to really make the best of this.

I'm working on some performance numbers now with OpenOffice.org Writer 
as Tom suggested. I'll follow up on this later in this thread when I 
have some more data collected.

Keith


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-12-08 19:47   ` Keith Seitz
@ 2009-12-14 19:33     ` Keith Seitz
  2009-12-17 20:19       ` Tom Tromey
  0 siblings, 1 reply; 50+ messages in thread
From: Keith Seitz @ 2009-12-14 19:33 UTC (permalink / raw)
  To: gdb-patches

On 12/08/2009 11:47 AM, Keith Seitz wrote:
> Yeah, this is *really* bad. Really, really bad. But this was just a an
> attempt at "making it work." Now comes the "make it faster" part. I have
> a few ideas about redundant calls and whatnot, but it will undoubtedly
> take some real effort and refactoring to really make the best of this.
>
> I'm working on some performance numbers now with OpenOffice.org Writer
> as Tom suggested. I'll follow up on this later in this thread when I
> have some more data collected.

Okay, so I have some performance numbers for my box using CVS HEAD 
patched and unpatched with my dwarf2_physname patches.

Yes, --readnow and things like "info func" and "info types" will take a 
big performance hit (really big right now).

So, without further ado...

I did three tests, all with OpenOffice.org Writer, as Tom suggested. So 
when you see $PID, you'll know what PID that's for.

1. time ./gdb -nx -q --batch-silent --pid $PID 2> /dev/null

HEAD:
real    1m14.906s  0m14.517s  0m12.229s  0m12.669s  0m12.638s
user    0m19.050s  0m11.985s  0m11.770s  0m11.738s  0m11.754s
sys     0m1.998s   0m0.484s   0m0.448s   0m0.437s   0m0.431s

dwarf2_physname:
real    1m6.761s   0m12.143s  0m12.070s  0m12.098s  0m12.128s
user    0m18.863s  0m11.710s  0m11.652s  0m11.695s  0m11.683s
sys     0m1.954s   0m0.420s   0m0.390s   0m0.390s   0m0.413s

2. time ./gdb -nx -q --batch-silent --pid $PID -ex "thread apply all bt 
full" 2> /dev/null

HEAD:
real    1m9.236s   0m12.739s  0m12.619s  0m12.613s  0m12.565s
user    0m19.059s  0m12.178s  0m12.170s  0m12.166s  0m12.102s
sys     0m1.883s   0m0.433s   0m0.440s   0m0.434s   0m0.456s

dwarf2_physname:
real    1m8.355s   0m13.276s  0m13.211s  0m13.208s  0m13.138s
user    0m19.863s  0m12.679s  0m12.750s  0m12.708s  0m12.708s
sys     0m0.978s   0m0.465s   0m0.436s   0m0.422s   0m0.425s

3. time ./gdb -nx -q --batch-silent --readnow --pid $PID 2> /dev/null

HEAD:
real    10m42.371s  6m57.499s  6m2.538s   7m50.482s  6m46.206s
user    1m43.927s   1m40.768s  1m40.768s  1m40.673s  1m41.129s
sys     0m9.349s    0m7.875s   0m7.038s   0m8.751s   0m7.552s

dwarf2_realname:
real    774m37.623s
user    3m48.010s
sys     0m14.745s

As you can see, --readnow (and by extrapolation "info func" and "info 
type") take an enormous performance hit. The dwarf2_physname patch as it 
currently exists, though, appears to have a pretty minimal impact on 
performance for more "normal" or "mundane" usage.

In other news, I've tested linux native using STABS, and there are two 
test files that show a total of five regressions, which I am digging 
into. [I've eliminated another five failures because they also exist as 
"failures" in the DWARF case (the library is still using DWARF!).]

As I'm sure we all know, STABS and C++ are such horrible bedfellows to 
begin with...

Keith


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-12-14 19:33     ` Keith Seitz
@ 2009-12-17 20:19       ` Tom Tromey
  2009-12-17 20:28         ` Daniel Jacobowitz
  0 siblings, 1 reply; 50+ messages in thread
From: Tom Tromey @ 2009-12-17 20:19 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

>>>>> "Keith" == Keith Seitz <keiths@redhat.com> writes:

Keith> Okay, so I have some performance numbers for my box using CVS HEAD
Keith> patched and unpatched with my dwarf2_physname patches.

Thanks.

It looks to me like dwarf2_physname is not significantly slower in the
normal (attach and bt) cases -- only in the -readnow case.

Keith> dwarf2_realname:
Keith> real    774m37.623s

On irc Keith suggested that this may be due to swapping.

I probably wouldn't have let this test finish, myself :-)

Keith> As you can see, --readnow (and by extrapolation "info func" and
Keith> "info type") take an enormous performance hit.

I am not concerned about this.  I don't think -readnow is actually used
-- I can't imagine why anyone would want to use it.  And, on a big
program, an unrestricted "info func" or "info type" is probably just a
mistake, like hitting enter too soon.

I think we should wait a bit to see if there are other comments,
particularly because I imagine a lot of people are going on vacation
soon.

Tom


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-12-17 20:19       ` Tom Tromey
@ 2009-12-17 20:28         ` Daniel Jacobowitz
  2009-12-17 22:39           ` Paul Pluzhnikov
  2009-12-22 18:35           ` Tom Tromey
  0 siblings, 2 replies; 50+ messages in thread
From: Daniel Jacobowitz @ 2009-12-17 20:28 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Keith Seitz, gdb-patches

On Thu, Dec 17, 2009 at 01:19:49PM -0700, Tom Tromey wrote:
> Keith> As you can see, --readnow (and by extrapolation "info func" and
> Keith> "info type") take an enormous performance hit.
> 
> I am not concerned about this.  I don't think -readnow is actually used
> -- I can't imagine why anyone would want to use it.  And, on a big
> program, an unrestricted "info func" or "info type" is probably just a
> mistake, like hitting enter too soon.

Is there a way out if you do that?  Does QUIT work?  Also, does print
<tab> read all symtabs?

I'm not happy with introducing this slowdown.  I'd like to at least
see a profile first - of some smaller example!  But I guess you're
right that -readnow is not useful; maybe I should just let go...

I thought I did -readnow profiling on my previous patches in this
area without introducing such a big slowdown, but I don't know that
for a fact.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-12-17 20:28         ` Daniel Jacobowitz
@ 2009-12-17 22:39           ` Paul Pluzhnikov
  2009-12-22 18:35           ` Tom Tromey
  1 sibling, 0 replies; 50+ messages in thread
From: Paul Pluzhnikov @ 2009-12-17 22:39 UTC (permalink / raw)
  To: Tom Tromey, Keith Seitz, gdb-patches

On Thu, Dec 17, 2009 at 12:28 PM, Daniel Jacobowitz <drow@false.org> wrote:

>> And, on a big
>> program, an unrestricted "info func" or "info type" is probably just a
>> mistake, like hitting enter too soon.
>
> Is there a way out if you do that?  Does QUIT work?

QUIT used to not work for "info func". I fixed it here:
http://sourceware.org/ml/gdb-patches/2009-07/msg00573.html

I just checked, 'info type' in 7.0.50.20091211-cvs; QUIT appears to work
just fine.

Regards,
-- 
Paul Pluzhnikov


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-12-17 20:28         ` Daniel Jacobowitz
  2009-12-17 22:39           ` Paul Pluzhnikov
@ 2009-12-22 18:35           ` Tom Tromey
  2009-12-22 19:24             ` Daniel Jacobowitz
  1 sibling, 1 reply; 50+ messages in thread
From: Tom Tromey @ 2009-12-22 18:35 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

>>>>> "Daniel" == Daniel Jacobowitz <drow@false.org> writes:

Tom> I am not concerned about this.  I don't think -readnow is actually used
Tom> -- I can't imagine why anyone would want to use it.  And, on a big
Tom> program, an unrestricted "info func" or "info type" is probably just a
Tom> mistake, like hitting enter too soon.

Daniel> [...]  Also, does print
Daniel> <tab> read all symtabs?

It doesn't.  Keith's patch didn't touch the completion code.  This code
walks expanded symtabs, and then psymtabs -- it doesn't do any
expanding.  See symtab.c:default_make_symbol_completion_list.

Daniel> I'm not happy with introducing this slowdown.  I'd like to at least
Daniel> see a profile first - of some smaller example!  But I guess you're
Daniel> right that -readnow is not useful; maybe I should just let go...

:-)

My guess is that -readnow is left over from when GDB used mmalloc and
could dump symtabs.  That's just a guess, though.

I do agree that looking at a smaller example would be interesting,
because it would isolate the swap effect.

Tom


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-12-22 18:35           ` Tom Tromey
@ 2009-12-22 19:24             ` Daniel Jacobowitz
  2010-01-20 20:37               ` Keith Seitz
  0 siblings, 1 reply; 50+ messages in thread
From: Daniel Jacobowitz @ 2009-12-22 19:24 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Keith Seitz, gdb-patches

On Tue, Dec 22, 2009 at 11:35:15AM -0700, Tom Tromey wrote:
> I do agree that looking at a smaller example would be interesting,
> because it would isolate the swap effect.

Yes, please.  But after that, I'm prepared to ignore the -readnow
problem in the name of progress.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-12-22 19:24             ` Daniel Jacobowitz
@ 2010-01-20 20:37               ` Keith Seitz
  2010-01-26 21:17                 ` Daniel Jacobowitz
  0 siblings, 1 reply; 50+ messages in thread
From: Keith Seitz @ 2010-01-20 20:37 UTC (permalink / raw)
  To: gdb-patches

On 12/22/2009 11:24 AM, Daniel Jacobowitz wrote:
> On Tue, Dec 22, 2009 at 11:35:15AM -0700, Tom Tromey wrote:
>> I do agree that looking at a smaller example would be interesting,
>> because it would isolate the swap effect.
>
> Yes, please.  But after that, I'm prepared to ignore the -readnow
> problem in the name of progress.
>

Okay, I'm finally back to this, and I have some more numbers for you, 
this time using abiword (with pretty much ALL debug info for every 
library installed).

Same three scenarios as last time; F11 gcc, CVS HEAD (20100118) gdb, 
same gdb + dwarf2_physname patches:

1. time ./gdb -nx -q --batch-silent --pid $PID 2> /dev/null
HEAD:
real    0m20.242s  0m2.407s   0m2.418s   0m2.390s   0m2.416s
user    0m3.565s   0m2.224s   0m2.253s   0m2.225s   0m2.240s
sys     0m0.680s   0m0.184s   0m0.163s   0m0.165s   0m0.177s

dwarf2_physname:
real    0m3.747s   0m2.452s   0m2.447s   0m2.447s   0m2.457s
user    0m2.293s   0m2.283s   0m2.268s   0m2.267s   0m2.272s
sys     0m0.185s   0m0.168s   0m0.178s   0m0.178s   0m0.184s

2. time ./gdb -nx -q --batch-silent --pid $PID -ex "thread apply all bt 
full" 2> /dev/null
HEAD:
real    0m3.001s   0m2.422s   0m2.440s   0m2.462s   0m2.447s
user    0m2.277s   0m2.258s   0m2.250s   0m2.261s   0m2.251s
sys     0m0.184s   0m0.163s   0m0.189s   0m0.199s   0m0.190s

dwarf2_physname:
real    0m2.593s   0m2.502s   0m2.510s   0m2.513s   0m2.502s
user    0m2.335s   0m2.322s   0m2.349s   0m2.321s   0m2.334s
sys     0m0.166s   0m0.179s   0m0.160s   0m0.186s   0m0.157s

3. time ./gdb -nx -q --batch-silent --readnow --pid $PID 2> /dev/null
HEAD:
real    0m28.275s   0m10.996s   0m11.060s   0m11.035s   0m11.038s
user    0m12.346s   0m10.378s   0m10.473s   0m10.450s   0m10.436s
sys     0m1.082s    0m0.613s    0m0.567s    0m0.570s    0m0.583s

dwarf2_physname:
real    0m36.998s   0m17.212s   0m17.295s   0m17.304s   0m17.288s
user    0m18.684s   0m16.502s   0m16.537s   0m16.572s   0m16.585s
sys     0m1.188s    0m0.702s    0m0.740s    0m0.719s    0m0.689s


If there is ANYTHING anyone (Andre?) wants me to check, please let me know.

Keith


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-01-20 20:37               ` Keith Seitz
@ 2010-01-26 21:17                 ` Daniel Jacobowitz
  2010-01-27 19:12                   ` Keith Seitz
  0 siblings, 1 reply; 50+ messages in thread
From: Daniel Jacobowitz @ 2010-01-26 21:17 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Wed, Jan 20, 2010 at 12:37:23PM -0800, Keith Seitz wrote:
> 1. time ./gdb -nx -q --batch-silent --pid $PID 2> /dev/null
> HEAD:
> real    0m20.242s  0m2.407s   0m2.418s   0m2.390s   0m2.416s
> user    0m3.565s   0m2.224s   0m2.253s   0m2.225s   0m2.240s
> sys     0m0.680s   0m0.184s   0m0.163s   0m0.165s   0m0.177s
> 
> dwarf2_physname:
> real    0m3.747s   0m2.452s   0m2.447s   0m2.447s   0m2.457s
> user    0m2.293s   0m2.283s   0m2.268s   0m2.267s   0m2.272s
> sys     0m0.185s   0m0.168s   0m0.178s   0m0.178s   0m0.184s

Consistently more, but not a major impact.

> 2. time ./gdb -nx -q --batch-silent --pid $PID -ex "thread apply all
> bt full" 2> /dev/null
> HEAD:
> real    0m3.001s   0m2.422s   0m2.440s   0m2.462s   0m2.447s
> user    0m2.277s   0m2.258s   0m2.250s   0m2.261s   0m2.251s
> sys     0m0.184s   0m0.163s   0m0.189s   0m0.199s   0m0.190s
> 
> dwarf2_physname:
> real    0m2.593s   0m2.502s   0m2.510s   0m2.513s   0m2.502s
> user    0m2.335s   0m2.322s   0m2.349s   0m2.321s   0m2.334s
> sys     0m0.166s   0m0.179s   0m0.160s   0m0.186s   0m0.157s

Ditto.  A little bigger than previously, but still not much.

> 3. time ./gdb -nx -q --batch-silent --readnow --pid $PID 2> /dev/null
> HEAD:
> real    0m28.275s   0m10.996s   0m11.060s   0m11.035s   0m11.038s
> user    0m12.346s   0m10.378s   0m10.473s   0m10.450s   0m10.436s
> sys     0m1.082s    0m0.613s    0m0.567s    0m0.570s    0m0.583s
> 
> dwarf2_physname:
> real    0m36.998s   0m17.212s   0m17.295s   0m17.304s   0m17.288s
> user    0m18.684s   0m16.502s   0m16.537s   0m16.572s   0m16.585s
> sys     0m1.188s    0m0.702s    0m0.740s    0m0.719s    0m0.689s

Not nearly as bad as I expected.

I think that this means we should move on past the speed concern for
now, and focus on any other issues in the patch.  Where were we on
that front?

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2009-11-24 19:20       ` Sami Wagiaalla
@ 2010-01-27 17:10         ` Sami Wagiaalla
  0 siblings, 0 replies; 50+ messages in thread
From: Sami Wagiaalla @ 2010-01-27 17:10 UTC (permalink / raw)
  To: gdb-patches

On 11/24/2009 02:21 PM, Sami Wagiaalla wrote:
> On 11/23/2009 12:07 PM, Daniel Jacobowitz wrote:
>> On Mon, Nov 23, 2009 at 08:51:16AM -0800, Keith Seitz wrote:
>>> On 11/20/2009 02:09 PM, Daniel Jacobowitz wrote:
>>>
>>>> I am generally opposed to committing known regressions. If there are
>>>> supporting patches we need to get in first, let's do that; if there
>>>> are tests we decide to break, let's XFAIL or KFAIL them. That's the
>>>> only way we can make the testsuite more useful.
>>>
>>> Sami has a follow-on patch that he could submit to fix all of these
>>> tests (they all pass on archer-keiths-expr-cumulative). Perhaps it
>>> would be acceptable for Sami to submit that patchset when/if this
>>> patch is accepted? [His patches rely on this patchset.]
>>
>> If it applies on top of this, could he post it now? Then we can treat
>> them as a unit for review and testing purposes.
>>
>
> I looked into this. It turns out that this is fixed by the patches
> posted on the thread rooted at this message
> http://sourceware.org/ml/gdb-patches/2009-07/msg00305.html
>

These patches have been approved and committed.

Sami


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-01-26 21:17                 ` Daniel Jacobowitz
@ 2010-01-27 19:12                   ` Keith Seitz
  2010-01-28 20:22                     ` Keith Seitz
  0 siblings, 1 reply; 50+ messages in thread
From: Keith Seitz @ 2010-01-27 19:12 UTC (permalink / raw)
  To: gdb-patches

On 01/26/2010 01:17 PM, Daniel Jacobowitz wrote:
> I think that this means we should move on past the speed concern for
> now, and focus on any other issues in the patch.  Where were we on
> that front?

I've merged with CVS HEAD again, but I see some regressions lying about. 
I believe we've mentioned (and perhaps discussed) a few of these before. 
Some involve fixing the test suite; some are java regressions (which I 
working to fix now -- I *think* I may be getting close).

Let me grab Sami's last commit, re-run and see where we stand.

Keith


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-01-27 19:12                   ` Keith Seitz
@ 2010-01-28 20:22                     ` Keith Seitz
  2010-01-28 20:24                       ` Daniel Jacobowitz
  0 siblings, 1 reply; 50+ messages in thread
From: Keith Seitz @ 2010-01-28 20:22 UTC (permalink / raw)
  To: gdb-patches

On 01/27/2010 11:12 AM, Keith Seitz wrote:
> On 01/26/2010 01:17 PM, Daniel Jacobowitz wrote:
>> I think that this means we should move on past the speed concern for
>> now, and focus on any other issues in the patch. Where were we on
>> that front?
>
> Let me grab Sami's last commit, re-run and see where we stand.

Okay, after some *more* linespec hacking, I have eliminated all the 
regressions in the test suite (including some java failures that exist 
on my archer-keiths-expr-cumulative branch).

Here is the summary for CVS HEAD on my box (updated yesterday):
# of expected passes		15396
# of unexpected failures	47
# of expected failures		43
# of untested testcases		14
# of unsupported tests		10


Same + my dwarf2_physname patches (including the cpexprs.exp tests):
# of expected passes		15790
# of unexpected failures	40
# of expected failures		43
# of untested testcases		14
# of unsupported tests		10

Diffs between the two (trivial test case fixes omitted):

   PASS: gdb.cp/classes.exp: print cnsi with static members
   PASS: gdb.cp/classes.exp: finish from marker_reg1
   PASS: gdb.cp/classes.exp: calling method for small class
! FAIL: gdb.cp/classes.exp: print ctor of typedef class
   PASS: gdb.cp/classes.exp: print dtor of typedef class
   PASS: gdb.cp/classes.exp: list ByAnyOtherName::times
   Running ../../../src/gdb/testsuite/gdb.cp/cpcompletion.exp ...
--- 10217,10223 ----
   PASS: gdb.cp/classes.exp: print cnsi with static members
   PASS: gdb.cp/classes.exp: finish from marker_reg1
   PASS: gdb.cp/classes.exp: calling method for small class
! PASS: gdb.cp/classes.exp: print ctor of typedef class
   PASS: gdb.cp/classes.exp: print dtor of typedef class
   PASS: gdb.cp/classes.exp: list ByAnyOtherName::times
   Running ../../../src/gdb/testsuite/gdb.cp/cpcompletion.exp ...
*************** PASS: gdb.cp/cpcompletion.exp: complete
*** 10227,10234 ****
--- 10227,10615 ----
   PASS: gdb.cp/cpcompletion.exp: complete p a.g
   PASS: gdb.cp/cpcompletion.exp: complete class methods
   PASS: gdb.cp/cpcompletion.exp: complete class methods beginning with F
+ Running ../../../src/gdb/testsuite/gdb.cp/cpexprs.exp ...
+ PASS: gdb.cp/cpexprs.exp: set listsize 1
+ PASS: gdb.cp/cpexprs.exp: print base1::a_function
+ PASS: gdb.cp/cpexprs.exp: print base1::base1(int)
+ PASS: gdb.cp/cpexprs.exp: print base1::base1(void)
+ PASS: gdb.cp/cpexprs.exp: print base2::a_function
+ PASS: gdb.cp/cpexprs.exp: print base2::base2
+ PASS: gdb.cp/cpexprs.exp: print base::base(int)
+ PASS: gdb.cp/cpexprs.exp: print base::base(void)
+ PASS: gdb.cp/cpexprs.exp: print base::operator char*
+ PASS: gdb.cp/cpexprs.exp: print base::operator delete
+ PASS: gdb.cp/cpexprs.exp: print base::operator delete[]
+ PASS: gdb.cp/cpexprs.exp: print base::operator fluff*
+ PASS: gdb.cp/cpexprs.exp: print base::operator fluff**
+ PASS: gdb.cp/cpexprs.exp: print base::operator int
+ PASS: gdb.cp/cpexprs.exp: print base::operator new
+ PASS: gdb.cp/cpexprs.exp: print base::operator new[]
+ PASS: gdb.cp/cpexprs.exp: print base::operator!
+ PASS: gdb.cp/cpexprs.exp: print base::operator!=
+ PASS: gdb.cp/cpexprs.exp: print base::operator%
+ PASS: gdb.cp/cpexprs.exp: print base::operator%=
+ PASS: gdb.cp/cpexprs.exp: print base::operator&
+ PASS: gdb.cp/cpexprs.exp: print base::operator&&
+ PASS: gdb.cp/cpexprs.exp: print base::operator&=
+ PASS: gdb.cp/cpexprs.exp: print base::operator()
+ PASS: gdb.cp/cpexprs.exp: print base::operator*
+ PASS: gdb.cp/cpexprs.exp: print base::operator*=
+ PASS: gdb.cp/cpexprs.exp: print base::operator+
+ PASS: gdb.cp/cpexprs.exp: print base::operator++
+ PASS: gdb.cp/cpexprs.exp: print base::operator+=
+ PASS: gdb.cp/cpexprs.exp: print base::operator-
+ PASS: gdb.cp/cpexprs.exp: print base::operator--
+ PASS: gdb.cp/cpexprs.exp: print base::operator-=
+ PASS: gdb.cp/cpexprs.exp: print base::operator/
+ PASS: gdb.cp/cpexprs.exp: print base::operator/=
+ PASS: gdb.cp/cpexprs.exp: print base::operator<
+ PASS: gdb.cp/cpexprs.exp: print base::operator<<
+ PASS: gdb.cp/cpexprs.exp: print base::operator<<=
+ PASS: gdb.cp/cpexprs.exp: print base::operator<=
+ PASS: gdb.cp/cpexprs.exp: print base::operator=
+ PASS: gdb.cp/cpexprs.exp: print base::operator==
+ PASS: gdb.cp/cpexprs.exp: print base::operator>
+ PASS: gdb.cp/cpexprs.exp: print base::operator>=
+ PASS: gdb.cp/cpexprs.exp: print base::operator>>
+ PASS: gdb.cp/cpexprs.exp: print base::operator>>=
+ PASS: gdb.cp/cpexprs.exp: print base::operator[]
+ PASS: gdb.cp/cpexprs.exp: print base::operator^
+ PASS: gdb.cp/cpexprs.exp: print base::operator^=
+ PASS: gdb.cp/cpexprs.exp: print base::operator|
+ PASS: gdb.cp/cpexprs.exp: print base::operator|=
+ PASS: gdb.cp/cpexprs.exp: print base::operator||
+ PASS: gdb.cp/cpexprs.exp: print base::operator~
+ PASS: gdb.cp/cpexprs.exp: print base::overload(base&) const
+ PASS: gdb.cp/cpexprs.exp: print base::overload(char*) const
+ PASS: gdb.cp/cpexprs.exp: print base::overload(int) const
+ PASS: gdb.cp/cpexprs.exp: print base::overload(long) const
+ PASS: gdb.cp/cpexprs.exp: print base::overload(short) const
+ PASS: gdb.cp/cpexprs.exp: print base::overload(void)
+ PASS: gdb.cp/cpexprs.exp: print base::overload(void) const
+ PASS: gdb.cp/cpexprs.exp: print base::~base
+ PASS: gdb.cp/cpexprs.exp: print derived::a_function
+ PASS: gdb.cp/cpexprs.exp: print derived::derived
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, char, char>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, char, int>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, char, long>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, char, short>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, int, char>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, int, int>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, int, long>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, int, short>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, long, char>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, long, int>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, long, long>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, long, short>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, short, char>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, short, int>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, short, long>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, int, short, short>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, short, int, char>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, short, int, int>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, short, int, long>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, short, int, short>
+ PASS: gdb.cp/cpexprs.exp: print flubber<int, int, short, short, int>
+ PASS: gdb.cp/cpexprs.exp: print flubber<long, short, long, short, long>
+ PASS: gdb.cp/cpexprs.exp: print flubber<short, int, short, int, short>
+ PASS: gdb.cp/cpexprs.exp: print main
+ PASS: gdb.cp/cpexprs.exp: print policy1::function
+ PASS: gdb.cp/cpexprs.exp: print policy1::policy
+ PASS: gdb.cp/cpexprs.exp: print policy2::function
+ PASS: gdb.cp/cpexprs.exp: print policy2::policy
+ PASS: gdb.cp/cpexprs.exp: print policy3::function
+ PASS: gdb.cp/cpexprs.exp: print policy3::policy
+ PASS: gdb.cp/cpexprs.exp: print policy4::function
+ PASS: gdb.cp/cpexprs.exp: print policy4::policy
+ PASS: gdb.cp/cpexprs.exp: print policyd1::function
+ PASS: gdb.cp/cpexprs.exp: print policyd1::policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd1::~policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd2::function
+ PASS: gdb.cp/cpexprs.exp: print policyd2::policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd2::~policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd3::function
+ PASS: gdb.cp/cpexprs.exp: print policyd3::policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd3::~policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd4::function
+ PASS: gdb.cp/cpexprs.exp: print policyd4::policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd4::~policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd5::function
+ PASS: gdb.cp/cpexprs.exp: print policyd5::policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd5::~policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd<base, operation_1<base> 
 >::function
+ PASS: gdb.cp/cpexprs.exp: print policyd<base, operation_1<base> >::policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd<base, operation_1<base> 
 >::~policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd<char, operation_1<char> 
 >::function
+ PASS: gdb.cp/cpexprs.exp: print policyd<char, operation_1<char> >::policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd<char, operation_1<char> 
 >::~policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd<int, operation_1<int> >::function
+ PASS: gdb.cp/cpexprs.exp: print policyd<int, operation_1<int> >::policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd<int, operation_1<int> >::~policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd<long, operation_1<long> >::policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd<long, operation_1<long> 
 >::~policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd<tclass<int>, 
operation_1<tclass<int> > >::function
+ PASS: gdb.cp/cpexprs.exp: print policyd<tclass<int>, 
operation_1<tclass<int> > >::policyd
+ PASS: gdb.cp/cpexprs.exp: print policyd<tclass<int>, 
operation_1<tclass<int> > >::~policyd
+ PASS: gdb.cp/cpexprs.exp: print tclass<base>::do_something
+ PASS: gdb.cp/cpexprs.exp: print tclass<char>::do_something
+ PASS: gdb.cp/cpexprs.exp: print tclass<int>::do_something
+ PASS: gdb.cp/cpexprs.exp: print tclass<long>::do_something
+ PASS: gdb.cp/cpexprs.exp: print tclass<short>::do_something
+ PASS: gdb.cp/cpexprs.exp: list base1::a_function
+ PASS: gdb.cp/cpexprs.exp: list base1::base1(int)
+ PASS: gdb.cp/cpexprs.exp: list base1::base1(void)
+ PASS: gdb.cp/cpexprs.exp: list base2::a_function
+ PASS: gdb.cp/cpexprs.exp: list base2::base2
+ PASS: gdb.cp/cpexprs.exp: list base::base(int)
+ PASS: gdb.cp/cpexprs.exp: list base::base(void)
+ PASS: gdb.cp/cpexprs.exp: list base::operator char*
+ PASS: gdb.cp/cpexprs.exp: list base::operator delete
+ PASS: gdb.cp/cpexprs.exp: list base::operator delete[]
+ PASS: gdb.cp/cpexprs.exp: list base::operator fluff*
+ PASS: gdb.cp/cpexprs.exp: list base::operator fluff**
+ PASS: gdb.cp/cpexprs.exp: list base::operator int
+ PASS: gdb.cp/cpexprs.exp: list base::operator new
+ PASS: gdb.cp/cpexprs.exp: list base::operator new[]
+ PASS: gdb.cp/cpexprs.exp: list base::operator!
+ PASS: gdb.cp/cpexprs.exp: list base::operator!=
+ PASS: gdb.cp/cpexprs.exp: list base::operator%
+ PASS: gdb.cp/cpexprs.exp: list base::operator%=
+ PASS: gdb.cp/cpexprs.exp: list base::operator&
+ PASS: gdb.cp/cpexprs.exp: list base::operator&&
+ PASS: gdb.cp/cpexprs.exp: list base::operator&=
+ PASS: gdb.cp/cpexprs.exp: list base::operator()
+ PASS: gdb.cp/cpexprs.exp: list base::operator*
+ PASS: gdb.cp/cpexprs.exp: list base::operator*=
+ PASS: gdb.cp/cpexprs.exp: list base::operator+
+ PASS: gdb.cp/cpexprs.exp: list base::operator++
+ PASS: gdb.cp/cpexprs.exp: list base::operator+=
+ PASS: gdb.cp/cpexprs.exp: list base::operator-
+ PASS: gdb.cp/cpexprs.exp: list base::operator--
+ PASS: gdb.cp/cpexprs.exp: list base::operator-=
+ PASS: gdb.cp/cpexprs.exp: list base::operator/
+ PASS: gdb.cp/cpexprs.exp: list base::operator/=
+ PASS: gdb.cp/cpexprs.exp: list base::operator<
+ PASS: gdb.cp/cpexprs.exp: list base::operator<<
+ PASS: gdb.cp/cpexprs.exp: list base::operator<<=
+ PASS: gdb.cp/cpexprs.exp: list base::operator<=
+ PASS: gdb.cp/cpexprs.exp: list base::operator=
+ PASS: gdb.cp/cpexprs.exp: list base::operator==
+ PASS: gdb.cp/cpexprs.exp: list base::operator>
+ PASS: gdb.cp/cpexprs.exp: list base::operator>=
+ PASS: gdb.cp/cpexprs.exp: list base::operator>>
+ PASS: gdb.cp/cpexprs.exp: list base::operator>>=
+ PASS: gdb.cp/cpexprs.exp: list base::operator[]
+ PASS: gdb.cp/cpexprs.exp: list base::operator^
+ PASS: gdb.cp/cpexprs.exp: list base::operator^=
+ PASS: gdb.cp/cpexprs.exp: list base::operator|
+ PASS: gdb.cp/cpexprs.exp: list base::operator|=
+ PASS: gdb.cp/cpexprs.exp: list base::operator||
+ PASS: gdb.cp/cpexprs.exp: list base::operator~
+ PASS: gdb.cp/cpexprs.exp: list base::overload(base&) const
+ PASS: gdb.cp/cpexprs.exp: list base::overload(char*) const
+ PASS: gdb.cp/cpexprs.exp: list base::overload(int) const
+ PASS: gdb.cp/cpexprs.exp: list base::overload(long) const
+ PASS: gdb.cp/cpexprs.exp: list base::overload(short) const
+ FAIL: gdb.cp/cpexprs.exp: list base::overload(void)
+ PASS: gdb.cp/cpexprs.exp: list base::overload(void) const
+ PASS: gdb.cp/cpexprs.exp: list base::~base
+ PASS: gdb.cp/cpexprs.exp: list derived::a_function
+ PASS: gdb.cp/cpexprs.exp: list derived::derived
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, char, char>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, char, int>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, char, long>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, char, short>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, int, char>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, int, int>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, int, long>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, int, short>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, long, char>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, long, int>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, long, long>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, long, short>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, short, char>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, short, int>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, short, long>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, int, short, short>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, short, int, char>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, short, int, int>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, short, int, long>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, short, int, short>
+ PASS: gdb.cp/cpexprs.exp: list flubber<int, int, short, short, int>
+ PASS: gdb.cp/cpexprs.exp: list flubber<long, short, long, short, long>
+ PASS: gdb.cp/cpexprs.exp: list flubber<short, int, short, int, short>
+ PASS: gdb.cp/cpexprs.exp: list main
+ PASS: gdb.cp/cpexprs.exp: list policy1::function
+ PASS: gdb.cp/cpexprs.exp: list policy1::policy
+ PASS: gdb.cp/cpexprs.exp: list policy2::function
+ PASS: gdb.cp/cpexprs.exp: list policy2::policy
+ PASS: gdb.cp/cpexprs.exp: list policy3::function
+ PASS: gdb.cp/cpexprs.exp: list policy3::policy
+ PASS: gdb.cp/cpexprs.exp: list policy4::function
+ PASS: gdb.cp/cpexprs.exp: list policy4::policy
+ PASS: gdb.cp/cpexprs.exp: list policyd1::function
+ PASS: gdb.cp/cpexprs.exp: list policyd1::policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd1::~policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd2::function
+ PASS: gdb.cp/cpexprs.exp: list policyd2::policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd2::~policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd3::function
+ PASS: gdb.cp/cpexprs.exp: list policyd3::policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd3::~policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd4::function
+ PASS: gdb.cp/cpexprs.exp: list policyd4::policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd4::~policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd5::function
+ PASS: gdb.cp/cpexprs.exp: list policyd5::policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd5::~policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd<base, operation_1<base> >::function
+ PASS: gdb.cp/cpexprs.exp: list policyd<base, operation_1<base> >::policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd<base, operation_1<base> >::~policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd<char, operation_1<char> >::function
+ PASS: gdb.cp/cpexprs.exp: list policyd<char, operation_1<char> >::policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd<char, operation_1<char> >::~policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd<int, operation_1<int> >::function
+ PASS: gdb.cp/cpexprs.exp: list policyd<int, operation_1<int> >::policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd<int, operation_1<int> >::~policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd<long, operation_1<long> >::policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd<long, operation_1<long> >::~policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd<tclass<int>, 
operation_1<tclass<int> > >::function
+ PASS: gdb.cp/cpexprs.exp: list policyd<tclass<int>, 
operation_1<tclass<int> > >::policyd
+ PASS: gdb.cp/cpexprs.exp: list policyd<tclass<int>, 
operation_1<tclass<int> > >::~policyd
+ PASS: gdb.cp/cpexprs.exp: list tclass<base>::do_something
+ PASS: gdb.cp/cpexprs.exp: list tclass<char>::do_something
+ PASS: gdb.cp/cpexprs.exp: list tclass<int>::do_something
+ PASS: gdb.cp/cpexprs.exp: list tclass<long>::do_something
+ PASS: gdb.cp/cpexprs.exp: list tclass<short>::do_something
+ PASS: gdb.cp/cpexprs.exp: continue to base1::a_function
+ PASS: gdb.cp/cpexprs.exp: continue to base1::base1(int)
+ PASS: gdb.cp/cpexprs.exp: continue to base1::base1(void)
+ PASS: gdb.cp/cpexprs.exp: continue to base2::a_function
+ PASS: gdb.cp/cpexprs.exp: continue to base2::base2
+ PASS: gdb.cp/cpexprs.exp: continue to base::base(int)
+ PASS: gdb.cp/cpexprs.exp: continue to base::base(void)
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator char*
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator delete
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator delete[]
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator fluff*
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator fluff**
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator int
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator new
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator new[]
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator!
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator!=
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator%
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator%=
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator&
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator&&
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator&=
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator()
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator*
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator*=
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator+
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator++
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator+=
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator-
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator--
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator-=
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator/
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator/=
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator<
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator<<
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator<<=
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator<=
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator=
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator==
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator>
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator>=
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator>>
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator>>=
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator[]
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator^
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator^=
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator|
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator|=
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator||
+ PASS: gdb.cp/cpexprs.exp: continue to base::operator~
+ PASS: gdb.cp/cpexprs.exp: continue to base::overload(base&) const
+ PASS: gdb.cp/cpexprs.exp: continue to base::overload(char*) const
+ PASS: gdb.cp/cpexprs.exp: continue to base::overload(int) const
+ PASS: gdb.cp/cpexprs.exp: continue to base::overload(long) const
+ PASS: gdb.cp/cpexprs.exp: continue to base::overload(short) const
+ FAIL: gdb.cp/cpexprs.exp: setting breakpoint at base::overload(void)
+ FAIL: gdb.cp/cpexprs.exp: continue to base::overload(void)
+ PASS: gdb.cp/cpexprs.exp: continue to base::overload(void) const
+ PASS: gdb.cp/cpexprs.exp: continue to base::~base
+ PASS: gdb.cp/cpexprs.exp: continue to derived::a_function
+ PASS: gdb.cp/cpexprs.exp: continue to derived::derived
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, char, char>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, char, int>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, char, long>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, char, short>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, int, char>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, int, int>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, int, long>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, int, short>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, long, char>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, long, int>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, long, long>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, long, short>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, short, char>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, short, int>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, short, long>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, int, short, short>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, short, int, char>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, short, int, int>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, short, int, long>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, short, int, short>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<int, int, short, short, int>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<long, short, long, 
short, long>
+ PASS: gdb.cp/cpexprs.exp: continue to flubber<short, int, short, int, 
short>
+ PASS: gdb.cp/cpexprs.exp: continue to policy1::function
+ PASS: gdb.cp/cpexprs.exp: continue to policy1::policy
+ PASS: gdb.cp/cpexprs.exp: continue to policy2::function
+ PASS: gdb.cp/cpexprs.exp: continue to policy2::policy
+ PASS: gdb.cp/cpexprs.exp: continue to policy3::function
+ PASS: gdb.cp/cpexprs.exp: continue to policy3::policy
+ PASS: gdb.cp/cpexprs.exp: continue to policy4::function
+ PASS: gdb.cp/cpexprs.exp: continue to policy4::policy
+ PASS: gdb.cp/cpexprs.exp: continue to policyd1::function
+ PASS: gdb.cp/cpexprs.exp: continue to policyd1::policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd1::~policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd2::function
+ PASS: gdb.cp/cpexprs.exp: continue to policyd2::policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd2::~policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd3::function
+ PASS: gdb.cp/cpexprs.exp: continue to policyd3::policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd3::~policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd4::function
+ PASS: gdb.cp/cpexprs.exp: continue to policyd4::policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd4::~policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd5::function
+ PASS: gdb.cp/cpexprs.exp: continue to policyd5::policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd5::~policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd<base, operation_1<base> 
 >::function
+ PASS: gdb.cp/cpexprs.exp: continue to policyd<base, operation_1<base> 
 >::policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd<base, operation_1<base> 
 >::~policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd<char, operation_1<char> 
 >::function
+ PASS: gdb.cp/cpexprs.exp: continue to policyd<char, operation_1<char> 
 >::policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd<char, operation_1<char> 
 >::~policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd<int, operation_1<int> 
 >::function
+ PASS: gdb.cp/cpexprs.exp: continue to policyd<int, operation_1<int> 
 >::policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd<int, operation_1<int> 
 >::~policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd<long, operation_1<long> 
 >::policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd<long, operation_1<long> 
 >::~policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd<tclass<int>, 
operation_1<tclass<int> > >::function
+ PASS: gdb.cp/cpexprs.exp: continue to policyd<tclass<int>, 
operation_1<tclass<int> > >::policyd
+ PASS: gdb.cp/cpexprs.exp: continue to policyd<tclass<int>, 
operation_1<tclass<int> > >::~policyd
+ PASS: gdb.cp/cpexprs.exp: continue to tclass<base>::do_something
+ PASS: gdb.cp/cpexprs.exp: continue to tclass<char>::do_something
+ PASS: gdb.cp/cpexprs.exp: continue to tclass<int>::do_something
+ PASS: gdb.cp/cpexprs.exp: continue to tclass<long>::do_something
+ PASS: gdb.cp/cpexprs.exp: continue to tclass<short>::do_something
   Running ../../../src/gdb/testsuite/gdb.cp/cplusfuncs.exp ...
   PASS: gdb.cp/cplusfuncs.exp: detect dm_operator_comma
+ PASS: gdb.cp/cplusfuncs.exp: detect dm_operator_char_star
   PASS: gdb.cp/cplusfuncs.exp: detect dm_type_char_star
   PASS: gdb.cp/cplusfuncs.exp: detect dm_type_foo_ref
   PASS: gdb.cp/cplusfuncs.exp: detect dm_type_int_star
*************** PASS: gdb.cp/cplusfuncs.exp: detect dm_t
*** 10236,10241 ****
--- 10617,10627 ----
   PASS: gdb.cp/cplusfuncs.exp: detect dm_type_unsigned_int
   PASS: gdb.cp/cplusfuncs.exp: detect dm_type_void
   PASS: gdb.cp/cplusfuncs.exp: detect dm_type_void_star
+ PASS: gdb.cp/cplusfuncs.exp: detect dm_type_short
+ PASS: gdb.cp/cplusfuncs.exp: detect dm_type_unsigned_short
+ PASS: gdb.cp/cplusfuncs.exp: detect dm_type_long
+ PASS: gdb.cp/cplusfuncs.exp: detect dm_type_unsigned_long
+ PASS: gdb.cp/cplusfuncs.exp: detect dm_type_typedef
   PASS: gdb.cp/cplusfuncs.exp: print &'overload1arg(void)'
   PASS: gdb.cp/cplusfuncs.exp: print &'overload1arg(char)'
   PASS: gdb.cp/cplusfuncs.exp: print &'overload1arg(signed char)'
*************** PASS: gdb.cp/member-ptr.exp: set var pmf
*** 11639,11644 ****
--- 12025,12031 ----
   PASS: gdb.cp/member-ptr.exp: print *pmf
   PASS: gdb.cp/member-ptr.exp: ptype *pmf
   PASS: gdb.cp/member-ptr.exp: print (a.*pmf)(3)
+ PASS: gdb.cp/member-ptr.exp: ptype a.*pmf
   PASS: gdb.cp/member-ptr.exp: print diamond_pmi
   PASS: gdb.cp/member-ptr.exp: print diamond.*diamond_pmi
   PASS: gdb.cp/member-ptr.exp: print diamond.*left_pmf
*************** PASS: gdb.cp/namespace.exp: ptype OtherF
*** 11768,11782 ****
   KFAIL: gdb.cp/namespace.exp: ptype ::C::OtherFileClass (PRMS: gdb/1448)
   PASS: gdb.cp/namespace.exp: ptype C::OtherFileClass
   PASS: gdb.cp/namespace.exp: print cX
! FAIL: gdb.cp/namespace.exp: print 'F::cXf'
! FAIL: gdb.cp/namespace.exp: print F::cXf
! FAIL: gdb.cp/namespace.exp: print F::cXfX
   PASS: gdb.cp/namespace.exp: print X
! FAIL: gdb.cp/namespace.exp: print 'G::Xg'
! FAIL: gdb.cp/namespace.exp: print G::Xg
! FAIL: gdb.cp/namespace.exp: print G::XgX
! FAIL: gdb.cp/namespace.exp: print cXOtherFile
! FAIL: gdb.cp/namespace.exp: print XOtherFile
   PASS: gdb.cp/namespace.exp: print AAA::ALPHA
   Running ../../../src/gdb/testsuite/gdb.cp/namespace-nested-import.exp ...
   PASS: gdb.cp/namespace-nested-import.exp: print C::x
--- 12155,12169 ----
   KFAIL: gdb.cp/namespace.exp: ptype ::C::OtherFileClass (PRMS: gdb/1448)
   PASS: gdb.cp/namespace.exp: ptype C::OtherFileClass
   PASS: gdb.cp/namespace.exp: print cX
! PASS: gdb.cp/namespace.exp: print 'F::cXf'
! PASS: gdb.cp/namespace.exp: print F::cXf
! PASS: gdb.cp/namespace.exp: print F::cXfX
   PASS: gdb.cp/namespace.exp: print X
! PASS: gdb.cp/namespace.exp: print 'G::Xg'
! PASS: gdb.cp/namespace.exp: print G::Xg
! PASS: gdb.cp/namespace.exp: print G::XgX
! PASS: gdb.cp/namespace.exp: print cXOtherFile
! PASS: gdb.cp/namespace.exp: print XOtherFile
   PASS: gdb.cp/namespace.exp: print AAA::ALPHA
   Running ../../../src/gdb/testsuite/gdb.cp/namespace-nested-import.exp ...
   PASS: gdb.cp/namespace-nested-import.exp: print C::x
*************** Running ../../../src/gdb/testsuite/gdb.c
*** 12051,12057 ****
   PASS: gdb.cp/templates.exp: set multiple-symbols ask
   KFAIL: gdb.cp/templates.exp: ptype T5<int> (PRMS: gdb/1111)
   KFAIL: gdb.cp/templates.exp: ptype T5<int> (PRMS: gdb/1111)
! KFAIL: gdb.cp/templates.exp: constructor breakpoint (PRMS: gdb/1062)
   PASS: gdb.cp/templates.exp: destructor breakpoint
   PASS: gdb.cp/templates.exp: value method breakpoint
   PASS: gdb.cp/templates.exp: breakpoint on a line with no real code
--- 12438,12444 ----
   PASS: gdb.cp/templates.exp: set multiple-symbols ask
   KFAIL: gdb.cp/templates.exp: ptype T5<int> (PRMS: gdb/1111)
   KFAIL: gdb.cp/templates.exp: ptype T5<int> (PRMS: gdb/1111)
! PASS: gdb.cp/templates.exp: constructor breakpoint
   PASS: gdb.cp/templates.exp: destructor breakpoint
   PASS: gdb.cp/templates.exp: value method breakpoint
   PASS: gdb.cp/templates.exp: breakpoint on a line with no real code

And yes, there are three failures in cpexprs.exp -- those all have to do 
with the inability of linespecs to deal properly with const methods when 
the user doesn't tell gdb that the method is const.

Keith

PS. Just a reminder how CVS HEAD does with cpexprs.exp:

# of expected passes		77
# of unexpected failures	54
# of unresolved testcases	247

[Yes, gdb crashes along the way.]


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-01-28 20:22                     ` Keith Seitz
@ 2010-01-28 20:24                       ` Daniel Jacobowitz
  2010-01-28 23:41                         ` Keith Seitz
  0 siblings, 1 reply; 50+ messages in thread
From: Daniel Jacobowitz @ 2010-01-28 20:24 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Thu, Jan 28, 2010 at 12:22:35PM -0800, Keith Seitz wrote:
> On 01/27/2010 11:12 AM, Keith Seitz wrote:
> >On 01/26/2010 01:17 PM, Daniel Jacobowitz wrote:
> >>I think that this means we should move on past the speed concern for
> >>now, and focus on any other issues in the patch. Where were we on
> >>that front?
> >
> >Let me grab Sami's last commit, re-run and see where we stand.
> 
> Okay, after some *more* linespec hacking, I have eliminated all the
> regressions in the test suite (including some java failures that
> exist on my archer-keiths-expr-cumulative branch).

Great!  Want to resubmit the patch, then?

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-01-28 20:24                       ` Daniel Jacobowitz
@ 2010-01-28 23:41                         ` Keith Seitz
  2010-02-01 16:48                           ` Daniel Jacobowitz
  0 siblings, 1 reply; 50+ messages in thread
From: Keith Seitz @ 2010-01-28 23:41 UTC (permalink / raw)
  To: gdb-patches

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

On 01/28/2010 12:24 PM, Daniel Jacobowitz wrote:
>
> Great!  Want to resubmit the patch, then?

Attached.

Ok, DON'T try to apply the dwarf2_physname*-2.patch files. I've 
hand-edited them to keep the "meat" separate from the trivial changes. 
These are also based on yesterday's repo.

If you want to apply the patch, use the one called 
dwarf2_physname-20100128.patch. That's just a blanket diff on my local 
sandbox, updated against CVS HEAD today.

Keith

PS. I've had to pull a few patches from expr-cumulative. I have made a 
concerted effort to credit authors with their work, but I may have 
overlooked something. I apologize in advance if I have accidentally 
omitted to credit Tom, Sami, or Jan for any of their work which I pulled 
in for this submission.

*** ChangeLog -- dwarf2_physname-2.patch

2009-11-20  Keith Seitz  <keiths@redhat.com>

	Based on work from Daniel Jacobowitz  <dan@codesourcery.com>
	* c-typeprint.c (cp_type_print_method_args): For non-static methods,
	print out const or volatile qualifiers, too.
	(c_type_print_args): Add parameters show_artificial and language.
	Skip artificial parameters when requested.
	Use the appropriate language printer.
	(c_type_print_varspec): Tell c_type_print_args to skip artificial
	parameters and pass language_c.
	* dwarf2read.c (die_list): New file global.
	(struct partial_die_info): Update comments for name field.
	(pdi_needs_namespace): Renamed to ...
	(die_needs_namespace): ... this. Rewrite.
	(dwarf2_linkage_name): Remove.
	(add_partial_symbol): Do not predicate the call to
	partial_die_full_name based on pdi_needs_namespace.
	Remove call to cp_check_possible_namespace_symbols and associated
	outdated comments.
	(guess_structure_name): Do not inspect child subprogram DIEs.
	(dwarf2_fullname): Update comments.
	Use die_needs_namespace to assist in computing the name.
	(read_func_scope): Use dwarf2_name to get the DIE's name.
	Use dwarf2_physname to get the "linkage name" of the DIE.
	(dwarf2_add_member_field): Use dwarf2_physname instead of
	dwarf2_linkage_name.
	(read_structure_type): For structs and classes, set TYPE_NAME, too.
	(determine_class): Remove.
	(read_partial_die): Ignore DW_AT_MIPS_linkage_name for all languages
	except Ada.
	(new_symbol): Unconditionally call dwarf2_name.
	Compute the "linkage name" using dwarf2_physname.
	Use dwarf2_name instead of dwarf2_full_name for enumerator DIEs.
	When determining to scan for anonymous C++ namespaces, ignore
	the linkage name.
	(physname_prefix): New function.
	(physname_prefix_1): New function.
	(dwarf2_physname): New function.
	(_initialize_dwarf2_read): Initialize die_list.
	* gnu-v3-eabi.c (gnu_v3_find_method_in): Remove unused variable
	physname.
	(gnu_v3_print_method_ptr): Use the physname for virtual methods
	without a demangled name.
	Print out type information for non-virtual methods.
         * linespec.c (decode_line_1): Force ANY string using "::" (or
	"." for java) to use decode_compound, and clean up any stray quoting.
         If we found a file symtab, re-evaluate whether the remainder 
is_quoted.
         (decode_compound): Stop consuming at an open parenthesis.
         Keep template parameters.
         Keep any overload information.
         Keep keywords like "const".
         Remove paren_pointer.
         Move is_quoted check from set_flags to here.
         Remove #if 0 code from 2000. Ten years is long enough.
         (find_method): Before comparing symbol names, canonicalize the 
string
         from the user.
         If a specific overload is requested, find it. Otherwise throw 
an error.
	(find_method_overload_end): New function.
	(set_flags): Remove.
         (decode_compound): Assume that parentheses are matched.
         It's a lot easier.
	* symtab.c (symbol_find_demangled_name): Add DMGL_VERBOSE flag
	to cplus_demangle.
	* linespec.c (decode_line_1): Keep important keywords like
	"const" and "volatile".
	* symtab.h (SYMBOL_CPLUS_DEMANGLED_NAME): Remove.
	* typeprint.h (c_type_print_args): Add declaration.
	* ui-file.c (do_ui_file_obsavestring): New function.
	(ui_file_obsavestring): New function.
	* ui-file.h (ui_file_obsavestring): Add declaration.
	* valops.c (find_overload_match): Resolve the object to
	a non-pointer type.
	If the object is a data member, search the object for the member
	and return with staticp set.
	Use SYMBOL_NATURAL_NAME instead of SYMBOL_CPLUS_DEMANGLED_NAME.
	Do not attempt to extract a function name from non-function types.
	If the extracted function name and the original name are the same,
	we don't have a C++ method.

	From Jan Kratochvil  <jan.kratochvil@redhat.com>:
     	* dwarf2read.c (new_symbol <DW_TAG_enumerator>): Call 
dwarf2_full_name.


*** ChangeLog -- dwarf2_physname-trivial-2.patch

2010-01-28  Keith Seitz  <keiths@redhat.com>

	* ada-lang.c (ada_lookup_symbol): Remove linkage_name parameters
	and arguments from symbol lookups.
	* ax-gdb.c (gen_expr): Likewise.
	* cp-namespace.c (cp_lookup_symbol_nonlocal, lookup_namespace_scope,
	cp_lookup_symbol_namespace, lookup_symbol_file, lookup_nested_type,
	lookup_possible_namespace_symbol): Likewise.
	* cp-support.c (read_in_psymtabs): Likewise.
	* cp-support.h (cp_lookup_symbol_nonlocal): Likewise.
	* language.h (la_lookup_symbol_nonlocal): Likewise.
	* scm-valprint.c (scm_inferior_print): Likewise.
	* solib-darwin.c (darwin_relocate_section_addresses): Likewise.
	* solib-svr.c (elf_lookup_lib): Likewise.
	* solib.c (show_auto_solib_add): Likewise.
	* solist.h (lookup_lib_global, solib_global_lookup): Likewise.
	* symmisc.c (maintenance_check_symtabs): Likewise.
	* symtab.c (lookup_symbol_in_language, lookup_symbol_aux,
	lookup_symbol_aux_local, lookup_symbol_aux_block,
	lookup_symbol_from_objfile, lookup_symbol_aux_symtabs,
	lookup_symbol_aux_psymtabs,basic_lookup_symbol_nonlocal,
	lookup_symbol_static, lookup_symbol_global, symbol_matches_domain,
	basic_lookup_transparent_type, find_main_psymtab,
	lookup_block_symbol): Likewise.
	* symtab.h (basic_lookp_symbol_nonlocal, lookup_symbol_static,
	lookup_symbol_global, lookup_symbol_aux_block,
	lookup_symbol_partial_symbol, lookup_block_symbol,
	lookup_global_symbol, value_maybe_namespace_elt): Likewise.



*** ChangeLog -- dwarf2_physname-tests-2.patch
2010-01-28  Keith Seitz  <keiths@redhat.com>

         * gdb.cp/cp-relocate.exp: Remove single-quoting of C++ methods.
         * gdb.cp/cplusfuncs.cc (dm_type_short): New function.
         (dm_type_long): New function.
         (dm_type_unsigned_short): New function.
         (dm_type_unsigned_long): New function.
         (myint): New typedef.
         * gdb.cp/cplusfuncs.exp (probe_demangler): Add tests for short,
         long, unsigned shor and long, operator char*, and typedef.
         (test_lookup_operator_functions): Add operator char* test.
         (test_paddr_operator_functions): Likewise.
         (test_paddr_overloaded_functions): Use probe values for
         short, long, and unsigned short and long.
         (test_paddr_hairy_functions): If the demangler probe detected
         gdb type printers, "expect" them. Otherwise "expect" the v2 or v3
         demangler.
         * gdb.cp/expand-sals.exp: Backtrace may contain class names.
         * gdb.cp/member-ptr.exp: Refine expected result for "print pmf"
         and "print null_pmf".
         Add test "ptype a.*pmf".
         * gdb.cp/overload.exp: Allow optional "int" to appear with
         "short" and "long".
         * gdb.cp/ovldbreak.exp: Use append to construct super-duper
         long expect value for men_overload1arg.
         Allow "int" to appear with "short" and "long".
         When testing "info break", add argument for main (void).
         Also allow "int" to appear with "short" and "long".
         Ditto with "unsigned" and "long long".
	* gdb.java/jmain.exp: Do not enclose methods names in single
	quotes.
	* gdb.java/jmisc.exp: Likewise.
	* gdb.java/jprint.exp: Likewise.

	From Jan Kratochvil  <jan.kratochvil@redhat.com>:
	* gdb.cp/exception.exp (backtrace after first throw)
	(backtrace after second throw): Allow a namespace before __cxa_throw.
	(backtrace after first catch, backtrace after second catch): Allow
	a namespace before __cxa_begin_catch.



*** ChangeLog -- cpexprs-2.patch

2010-01-28  Keith Seitz  <keiths@redhat.com>

	* gdb.cp/cpexprs.exp: New file.
	* gdb.cp/cpexprs.cc: New file.

	From Daniel Jacobowitz  <dan@codesourcery.com>
	* gdb.cp/cpexprs.exp (escape): Delete.  Change all callers
	to use string_to_regexp.
	(ctor, dtor): New functions.  Use them to match constructor
	and destructor function types.
	(Top level): Use runto_main.


[-- Attachment #2: cpexprs-2.patch --]
[-- Type: text/plain, Size: 31175 bytes --]

Index: testsuite/gdb.cp/cpexprs.exp
===================================================================
RCS file: testsuite/gdb.cp/cpexprs.exp
diff -N testsuite/gdb.cp/cpexprs.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/cpexprs.exp	28 Jan 2010 22:55:52 -0000
@@ -0,0 +1,724 @@
+# cpexprs.exp - C++ expressions tests
+#
+# Copyright 2008, 2009, 2010 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.
+
+# A helper proc which sets a breakpoint at FUNC and attempts to
+# run to the breakpoint.
+proc test_breakpoint {func} {
+    global DEC
+
+    # Restart every time
+    if {![runto_main]} {
+	perror "could not run to main when attempting to break at $func"
+    } else {
+	gdb_breakpoint "$func"
+	set i [expr {[string last : $func] + 1}]
+	set efunc [string_to_regexp [string range $func $i end]]
+	gdb_test "continue" \
+	    "Continuing.\r\n\r\nBreakpoint $DEC+,.*$efunc.*" \
+	    "continue to $func"
+    }
+}
+
+# Add a function to the list of tested functions
+# FUNC is the name of the function (which will be passed to gdb commands)
+# TYPE is the type of the function, as expected from the "print" command
+# PRINT is the name of the function, as expected result of the print command
+#  *OR* "-", indicating that FUNC should be used (needed for virtual/inherited
+#   funcs)
+# LST is either the expected result of the list command (the comment from
+#  the source code) *OR* "-", in which case FUNC will be used
+#
+# Usage:
+# add NAME TYPE PRINT LST
+# add NAME TYPE PRINT -
+proc add {func type print lst} {
+    global all_functions CONVAR ADDR
+
+    set all_functions($func,type) $type
+    if {$print == "-"} {
+	set print $func
+    }
+
+    # An exception: since gdb canonicalizes C++ output,
+    # "(void)" must be mutated to "()".
+    regsub {\(void\)} $print {()} print
+
+    set all_functions($func,print) \
+	"$CONVAR = {[string_to_regexp $type]} $ADDR <[string_to_regexp $print].*>"
+    if {$lst == "-"} {
+	set lst "$func"
+    }
+    set all_functions($func,list) ".*// [string_to_regexp $lst]"
+}
+
+proc get {func cmd} {
+    global all_functions
+    return $all_functions($func,$cmd)
+}
+
+# Returns a list of function names for a given command
+proc get_functions {cmd} {
+    global all_functions
+    set result {}
+    foreach i [array names all_functions *,$cmd] {
+	if {$all_functions($i) != ""} {
+	    set idx [string last , $i]
+	    if {$idx != -1} {
+		lappend result [string range $i 0 [expr {$idx - 1}]]
+	    }
+	}
+    }
+
+    return [lsort $result]
+}
+
+# Some convenience variables for this test
+set DEC {[0-9]}; # a decimal number
+set HEX {[0-9a-fA-F]}; # a hexidecimal number
+set CONVAR "\\\$$DEC+"; # convenience variable regexp
+set ADDR "0x$HEX+"; # address
+
+# An array of functions/methods that we are testing...
+# Each element consists is indexed by NAME,COMMAND, where
+# NAME is the function name and COMMAND is the gdb command that
+# we are testing. The value of the array for any index pair is
+# the expected result of running COMMAND with the NAME as argument.
+
+# The array holding all functions/methods to test. Valid subindexes
+# are (none need character escaping -- "add" will take care of that):
+
+# add name type print_name list
+# NAME,type: value is type of function 
+# NAME,print: value is print name of function (careful w/inherited/virtual!)
+# NAME,list: value is comment in source code on first line of function
+#   (without the leading "//")
+array set all_functions {}
+
+# "Normal" functions/methods
+add {main} \
+    {int (int, char **)} \
+    - \
+    -
+add {derived::a_function} \
+    {void (const derived * const)} \
+    - \
+    -
+add {base1::a_function} \
+    {void (const base1 * const)} \
+    - \
+    -
+add {base2::a_function} \
+    {void (const base2 * const)} \
+    - \
+    -
+
+# Constructors
+
+# On targets using the ARM EABI, the constructor is expected to return
+# "this".
+proc ctor { type arglist } {
+    if { [istarget arm*-*eabi*] } {
+	set ret "$type *"
+    } else {
+	set ret "void "
+    }
+    if { $arglist != "" } {
+	set arglist ", $arglist"
+    }
+    return "${ret}($type * const$arglist)"
+}
+
+add {derived::derived} \
+    [ctor derived ""] \
+    - \
+    -
+add {base1::base1(void)} \
+    [ctor base1 "const void ** const"] \
+    - \
+    -
+add {base1::base1(int)} \
+    [ctor base1 "int"] \
+    - \
+    -
+add {base2::base2} \
+    [ctor base2 "const void ** const"] \
+    - \
+    -
+add {base::base(void)} \
+    [ctor base ""] \
+    - \
+    -
+add {base::base(int)} \
+    [ctor base "int"] \
+    - \
+    -
+
+# Destructors
+
+# On targets using the ARM EABI, some destructors are expected
+# to return "this".  Others are void.  For internal reasons,
+# GCC returns void * instead of $type *; RealView appears to do
+# the same.
+proc dtor { type } {
+    if { [istarget arm*-*eabi*] } {
+	set ret "void *"
+    } else {
+	set ret "void "
+    }
+    return "${ret}($type * const)"
+}
+
+add {base::~base} \
+    [dtor base] \
+    - \
+    -
+
+# Overloaded methods (all are const -- we try to use the void
+# method with and without specifying "const")
+add {base::overload(void)} \
+    {int (const base * const)} \
+    - \
+    {base::overload(void) const}
+add {base::overload(void) const} \
+    {int (const base * const)} \
+    - \
+    {base::overload(void) const}
+add {base::overload(int) const} \
+    {int (const base * const, int)} \
+    - \
+    -
+add {base::overload(short) const} \
+    {int (const base * const, short)} \
+    - \
+    -
+add {base::overload(long) const} \
+    {int (const base * const, long)} \
+    - \
+    -
+add {base::overload(char*) const} \
+    {int (const base * const, char *)} \
+    - \
+    -
+add {base::overload(base&) const} \
+    {int (const base * const, base &)} \
+    - \
+    -
+
+# Operators
+add {base::operator+} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator++} \
+    {base (base * const)} \
+    - \
+    -
+add {base::operator+=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator-} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator--} \
+    {base (base * const)} \
+    - \
+    -
+add {base::operator-=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator*} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator*=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator/} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator/=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator%} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator%=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator<} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator<=} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator>} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator>=} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator!=} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator==} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator!} \
+    {bool (const base * const)} \
+    - \
+    -
+add {base::operator&&} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator||} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator<<} \
+    {int (const base * const, int)} \
+    - \
+    -
+add {base::operator<<=} \
+    {base (base * const, int)} \
+    - \
+    -
+add {base::operator>>} \
+    {int (const base * const, int)} \
+    - \
+    -
+add {base::operator>>=} \
+    {base (base * const, int)} \
+    - \
+    -
+add {base::operator~} \
+    {int (const base * const)} \
+    - \
+    -
+add {base::operator&} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator&=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator|} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator|=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator^} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator^=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator()} \
+    {void (const base * const)} \
+    - \
+    -
+add {base::operator[]} \
+    {int (const base * const, int)} \
+    - \
+    -
+add {base::operator new} \
+    {void *(size_t)} \
+    - \
+    -
+add {base::operator delete} \
+    {void (void *)} \
+    - \
+    -
+add {base::operator new[]} \
+    {void *(size_t)} \
+    - \
+    -
+add {base::operator delete[]} \
+    {void (void *)} \
+    - \
+    -
+add {base::operator char*} \
+    {char *(const base * const)} \
+    - \
+    -
+add {base::operator fluff*} \
+    {fluff *(const base * const)} \
+    - \
+    -
+add {base::operator fluff**} \
+    {fluff **(const base * const)} \
+    - \
+    -
+add {base::operator int} \
+    {int (const base * const)} \
+    - \
+    -
+
+# Templates
+add {tclass<char>::do_something} \
+    {void (tclass<char> * const)} \
+    - \
+    -
+add {tclass<int>::do_something} \
+    {void (tclass<int> * const)} \
+    - \
+    -
+add {tclass<long>::do_something} \
+    {void (tclass<long> * const)} \
+    - \
+    -
+add {tclass<short>::do_something} \
+    {void (tclass<short> * const)} \
+    - \
+    -
+add {tclass<base>::do_something} \
+    {void (tclass<base> * const)} \
+    - \
+    -
+add {flubber<int, int, int, int, int>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, int, short>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, int, long>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, int, char>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, short, int>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, short, short>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, short, long>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, short, char>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, long, int>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, long, short>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, long, long>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, long, char>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, char, int>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, char, short>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, char, long>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, char, char>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, short, int, int>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, short, int, short>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, short, int, long>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, short, int, char>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, short, short, int>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<short, int, short, int, short>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<long, short, long, short, long>} \
+    {void (void)} \
+    - \
+    flubber
+add {tclass<base>::do_something} \
+    {void (tclass<base> * const)} \
+    - \
+    {tclass<T>::do_something}
+add {policy1::policy} \
+    [ctor "policy<int, operation_1<void*> >" "int"] \
+    {policy<int, operation_1<void*> >::policy} \
+    {policy<T, Policy>::policy}
+add {policy2::policy} \
+    [ctor "policy<int, operation_2<void*> >" int] \
+    {policy<int, operation_2<void*> >::policy} \
+    {policy<T, Policy>::policy}
+add {policy3::policy} \
+    [ctor "policy<int, operation_3<void*> >" "int"] \
+    {policy<int, operation_3<void*> >::policy} \
+    {policy<T, Policy>::policy}
+add {policy4::policy} \
+    [ctor "policy<int, operation_4<void*> >" "int"] \
+    {policy<int, operation_4<void*> >::policy} \
+    {policy<T, Policy>::policy}
+add {policy1::function} \
+    {void (void)} \
+    {operation_1<void*>::function} \
+    {operation_1<T>::function}
+add {policy2::function} \
+    {void (void)} \
+    {operation_2<void*>::function} \
+    {operation_2<T>::function}
+add {policy3::function} \
+    {void (void)} \
+    {operation_3<void*>::function} \
+    {operation_3<T>::function}
+add {policy4::function} \
+    {void (void)} \
+    {operation_4<void*>::function} \
+    {operation_4<T>::function}
+add {policyd<int, operation_1<int> >::policyd} \
+    [ctor "policyd<int, operation_1<int> >" "int"] \
+    - \
+    {policyd<T, Policy>::policyd}
+add {policyd1::policyd} \
+    [ctor "policyd<int, operation_1<int> >" "int"] \
+    {policyd<int, operation_1<int> >::policyd} \
+    {policyd<T, Policy>::policyd}
+add {policyd<int, operation_1<int> >::~policyd} \
+    [dtor "policyd<int, operation_1<int> >"] \
+    - \
+    {policyd<T, Policy>::~policyd}
+add {policyd1::~policyd} \
+    [dtor "policyd<int, operation_1<int> >"] \
+    {policyd<int, operation_1<int> >::~policyd} \
+    {policyd<T, Policy>::~policyd}
+add {policyd<long, operation_1<long> >::policyd} \
+    [ctor "policyd<long, operation_1<long> >" "long"] \
+    - \
+    {policyd<T, Policy>::policyd}
+add {policyd2::policyd} \
+    [ctor "policyd<long, operation_1<long> >" "long"] \
+    {policyd<long, operation_1<long> >::policyd} \
+    {policyd<T, Policy>::policyd}
+add {policyd<long, operation_1<long> >::~policyd} \
+    [dtor "policyd<long, operation_1<long> >"] \
+    - \
+    {policyd<T, Policy>::~policyd}
+add {policyd2::~policyd} \
+    [dtor "policyd<long, operation_1<long> >"] \
+    {policyd<long, operation_1<long> >::~policyd} \
+    {policyd<T, Policy>::~policyd}
+add {policyd<char, operation_1<char> >::policyd} \
+    [ctor "policyd<char, operation_1<char> >" "char"] \
+    - \
+    {policyd<T, Policy>::policyd}
+add {policyd3::policyd} \
+    [ctor "policyd<char, operation_1<char> >" "char"] \
+    {policyd<char, operation_1<char> >::policyd} \
+    {policyd<T, Policy>::policyd}
+add {policyd<char, operation_1<char> >::~policyd} \
+    [dtor "policyd<char, operation_1<char> >"] \
+    - \
+    {policyd<T, Policy>::~policyd}
+add {policyd3::~policyd} \
+    [dtor "policyd<char, operation_1<char> >"] \
+    {policyd<char, operation_1<char> >::~policyd} \
+    {policyd<T, Policy>::~policyd}
+add {policyd<base, operation_1<base> >::policyd} \
+    [ctor "policyd<base, operation_1<base> >" "base"] \
+    - \
+    {policyd<T, Policy>::policyd}
+add {policyd4::policyd} \
+    [ctor "policyd<base, operation_1<base> >" "base"] \
+    {policyd<base, operation_1<base> >::policyd} \
+    {policyd<T, Policy>::policyd}
+add {policyd<base, operation_1<base> >::~policyd} \
+    [dtor "policyd<base, operation_1<base> >"] \
+    - \
+    {policyd<T, Policy>::~policyd}
+add {policyd4::~policyd} \
+    [dtor "policyd<base, operation_1<base> >"] \
+    {policyd<base, operation_1<base> >::~policyd} \
+    {policyd<T, Policy>::~policyd}
+add {policyd<tclass<int>, operation_1<tclass<int> > >::policyd} \
+    [ctor "policyd<tclass<int>, operation_1<tclass<int> > >" "tclass<int>"] \
+    - \
+    {policyd<T, Policy>::policyd}
+add {policyd5::policyd} \
+    [ctor "policyd<tclass<int>, operation_1<tclass<int> > >" "tclass<int>"] \
+    {policyd<tclass<int>, operation_1<tclass<int> > >::policyd} \
+    {policyd<T, Policy>::policyd}
+add {policyd<tclass<int>, operation_1<tclass<int> > >::~policyd} \
+    [dtor "policyd<tclass<int>, operation_1<tclass<int> > >"] \
+    - \
+    {policyd<T, Policy>::~policyd}
+add {policyd5::~policyd} \
+    [dtor "policyd<tclass<int>, operation_1<tclass<int> > >"] \
+    {policyd<tclass<int>, operation_1<tclass<int> > >::~policyd} \
+    {policyd<T, Policy>::~policyd}
+add {policyd<int, operation_1<int> >::function} \
+    {void (void)} \
+    {operation_1<int>::function}\
+    {operation_1<T>::function}
+add {policyd1::function} \
+    {void (void)} \
+    {operation_1<int>::function} \
+    {operation_1<T>::function}
+add {policyd2::function} \
+    {void (void)} \
+    {operation_1<long>::function} \
+    {operation_1<T>::function}
+add {policyd<char, operation_1<char> >::function} \
+    {void (void)} \
+    {operation_1<char>::function} \
+    {operation_1<T>::function}
+add {policyd3::function} \
+    {void (void)} \
+    {operation_1<char>::function} \
+    {operation_1<T>::function}
+add {policyd<base, operation_1<base> >::function} \
+    {void (void)} \
+    {operation_1<base>::function} \
+    {operation_1<T>::function}
+add {policyd4::function} \
+    {void (void)} \
+    {operation_1<base>::function} \
+    {operation_1<T>::function}
+add {policyd<tclass<int>, operation_1<tclass<int> > >::function} \
+    {void (void)} \
+    {operation_1<tclass<int> >::function} \
+    {operation_1<T>::function}
+add {policyd5::function} \
+    {void (void)} \
+    {operation_1<tclass<int> >::function} \
+    {operation_1<T>::function}
+
+# Start the test
+if {$tracelevel} {
+    strace $tracelevel
+}
+
+if {[skip_cplus_tests]} { continue }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "cpexprs"
+set srcfile "${testfile}.cc"
+set binfile [file join $objdir $subdir $testfile]
+
+if  {[gdb_compile [file join $srcdir $subdir $srcfile] $binfile \
+	  executable {debug c++}] != "" } {
+    untested "$testfile.exp"
+    return -1
+}
+
+if {[get_compiler_info $binfile "c++"]} {
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir [file join $srcdir $subdir]
+gdb_load $binfile
+
+if {![runto_main]} {
+    perror "couldn't run to breakpoint"
+    continue
+}
+
+# Set the listsize to one. This will help with testing "list".
+gdb_test "set listsize 1"
+
+# "print METHOD"
+foreach name [get_functions print] {
+    gdb_test "print $name" [get $name print] "print $name"
+}
+
+# "list METHOD"
+foreach name [get_functions list] {
+    gdb_test "list $name" [get $name list] "list $name"
+}
+
+# Running to breakpoint -- use any function we can "list"
+foreach name [get_functions list] {
+    # Skip "main", since test_breakpoint uses it
+    if {[string compare $name "main"] != 0} {
+	test_breakpoint $name
+    }
+}
+
+gdb_exit
+return 0
Index: testsuite/gdb.cp/cpexprs.cc
===================================================================
RCS file: testsuite/gdb.cp/cpexprs.cc
diff -N testsuite/gdb.cp/cpexprs.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/cpexprs.cc	28 Jan 2010 22:55:55 -0000
@@ -0,0 +1,431 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2008, 2009, 2010 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/>.
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@gnu.org  */
+
+#include <stdlib.h>
+#include <iostream>
+
+// Forward decls
+class base;
+class derived;
+
+// A simple template with specializations
+template <typename T>
+class tclass
+{
+public:
+  void do_something () { } // tclass<T>::do_something
+};
+
+template <>
+void tclass<char>::do_something () { } // tclass<char>::do_something
+
+template <>
+void tclass<int>::do_something () { } // tclass<int>::do_something
+
+template<>
+void tclass<long>::do_something () { } // tclass<long>::do_something
+
+template<>
+void tclass<short>::do_something () { } // tclass<short>::do_something
+
+// A simple template with multiple template parameters
+template <class A, class B, class C, class D, class E>
+void flubber (void) // flubber
+{
+  A a;
+  B b;
+  C c;
+  D d;
+  E e;
+
+  ++a;
+  ++b;
+  ++c;
+  ++d;
+  ++e;
+}
+
+// Some contrived policies
+template <class T>
+struct operation_1
+{
+  static void function (void) { } // operation_1<T>::function
+};
+
+template <class T>
+struct operation_2
+{
+  static void function (void) { } // operation_2<T>::function
+};
+
+template <class T>
+struct operation_3
+{
+  static void function (void) { } // operation_3<T>::function
+};
+
+template <class T>
+struct operation_4
+{
+  static void function (void) { } // operation_4<T>::function
+};
+
+// A policy-based class w/ and w/o default policy
+template <class T, class Policy>
+class policy : public Policy
+{
+public:
+  policy (T obj) : obj_ (obj) { } // policy<T, Policy>::policy
+
+private:
+  T obj_;
+};
+
+template <class T, class Policy = operation_1<T> >
+class policyd : public Policy
+{
+public:
+  policyd (T obj) : obj_ (obj) { } // policyd<T, Policy>::policyd
+  ~policyd (void) { } // policyd<T, Policy>::~policyd
+
+private:
+  T obj_;
+};
+
+typedef policy<int, operation_1<void*> > policy1;
+typedef policy<int, operation_2<void*> > policy2;
+typedef policy<int, operation_3<void*> > policy3;
+typedef policy<int, operation_4<void*> > policy4;
+
+typedef policyd<int> policyd1;
+typedef policyd<long> policyd2;
+typedef policyd<char> policyd3;
+typedef policyd<base> policyd4;
+typedef policyd<tclass<int> > policyd5;
+
+class fluff { };
+static fluff *g_fluff = new fluff ();
+
+class base
+{
+protected:
+  int foo_;
+
+public:
+  base (void) : foo_ (42) { } // base::base(void)
+  base (int foo) : foo_ (foo) { } // base::base(int)
+  ~base (void) { } // base::~base
+
+  // Some overloaded methods
+  int overload (void) const { return 0; } // base::overload(void) const
+  int overload (int i) const { return 1; } // base::overload(int) const
+  int overload (short s) const { return 2; } // base::overload(short) const
+  int overload (long l) const { return 3; } // base::overload(long) const
+  int overload (char* a) const { return 4; } // base::overload(char*) const
+  int overload (base& b) const { return 5; } // base::overload(base&) const
+
+  // Operators
+  int operator+ (base const& o) const // base::operator+
+  { return foo_ + o.foo_; }
+
+  base operator++ (void) // base::operator++
+  { ++foo_; return *this; }
+
+  base operator+=(base const& o) // base::operator+=
+  { foo_ += o.foo_; return *this; }
+
+  int operator- (base const& o) const // base::operator-
+  { return foo_ - o.foo_; }
+
+  base operator-- (void) // base::operator--
+  { --foo_; return *this; }
+
+  base operator-= (base const& o) // base::operator-=
+  { foo_ -= o.foo_; return *this; }
+
+  int operator* (base const& o) const // base::operator*
+  { return foo_ * o.foo_; }
+
+  base operator*= (base const& o) // base::operator*=
+  { foo_ *= o.foo_; return *this; }
+
+  int operator/ (base const& o) const // base::operator/
+  { return foo_ / o.foo_; }
+
+  base operator/= (base const& o) // base::operator/=
+  { foo_ /= o.foo_; return *this; }
+
+  int operator% (base const& o) const // base::operator%
+  { return foo_ % o.foo_; }
+  
+  base operator%= (base const& o) // base::operator%=
+  { foo_ %= o.foo_; return *this; }
+
+  bool operator< (base const& o) const // base::operator<
+  { return foo_ < o.foo_; }
+
+  bool operator<= (base const& o) const // base::operator<=
+  { return foo_ <= o.foo_; }
+
+  bool operator> (base const& o) const // base::operator>
+  { return foo_ > o.foo_; }
+
+  bool operator>= (base const& o) const // base::operator>=
+  { return foo_ >= o.foo_; }
+
+  bool operator!= (base const& o) const // base::operator!=
+  { return foo_ != o.foo_; }
+
+  bool operator== (base const& o) const // base::operator==
+  { return foo_ == o.foo_; }
+
+  bool operator! (void) const // base::operator!
+  { return !foo_; }
+
+  bool operator&& (base const& o) const // base::operator&&
+  { return foo_ && o.foo_; }
+
+  bool operator|| (base const& o) const // base::operator||
+  { return foo_ || o.foo_; }
+
+  int operator<< (int value) const // base::operator<<
+  { return foo_  << value; }
+
+  base operator<<= (int value) // base::operator<<=
+  { foo_ <<= value; return *this; }
+
+  int operator>> (int value) const // base::operator>>
+  { return foo_  >> value; }
+
+  base operator>>= (int value) // base::operator>>=
+  { foo_ >>= value; return *this; }
+
+  int operator~ (void) const // base::operator~
+  { return ~foo_; }
+
+  int operator& (base const& o) const // base::operator&
+  { return foo_ & o.foo_; }
+
+  base operator&= (base const& o) // base::operator&=
+  { foo_ &= o.foo_; return *this; }
+
+  int operator| (base const& o) const // base::operator|
+  { return foo_ | o.foo_; }
+
+  base operator|= (base const& o) // base::operator|=
+  { foo_ |= o.foo_; return *this; }
+  
+  int operator^ (base const& o) const // base::operator^
+  { return foo_ ^ o.foo_; }
+
+  base operator^= (base const& o) // base::operator^=
+  { foo_ ^= o.foo_; return *this; }
+
+  base operator= (base const& o) // base::operator=
+  { foo_ = o.foo_; return *this; }
+
+  void operator() (void) const // base::operator()
+  { return; }
+
+  int operator[] (int idx) const // base::operator[]
+  { return idx; }
+
+  void* operator new (size_t size) throw () // base::operator new
+  { return malloc (size); }
+
+  void operator delete (void* ptr) // base::operator delete
+  { free (ptr); }
+
+  void* operator new[] (size_t size) throw () // base::operator new[]
+  { return malloc (size); }
+
+  void operator delete[] (void* ptr) // base::operator delete[]
+  { free (ptr); }
+
+  base const* operator-> (void) const // base::opeartor->
+  { return this; }
+
+  int operator->* (base const& b) const // base::operator->*
+  {  return foo_ * b.foo_; }
+
+  operator char* () const { return const_cast<char*> ("hello"); } // base::operator char*
+  operator int () const { return 21; } // base::operator int
+  operator fluff* () const { return new fluff (); } // base::operator fluff*
+  operator fluff** () const { return &g_fluff; } // base::operator fluff**
+};
+
+class base1 : public virtual base
+{
+public:
+  base1 (void) : foo_ (21) { } // base1::base1(void)
+  base1 (int a) : foo_(a) { } // base1::base1(int)
+  void a_function (void) const { } // base1::a_function
+
+protected:
+  int foo_;
+};
+
+class base2 : public virtual base
+{
+public:
+  base2 () : foo_ (3) { } // base2::base2
+
+protected:
+  void a_function (void) const { } // base2::a_function
+  int foo_;
+};
+
+class derived : public base1, public base2
+{
+  public:
+  derived(void) : foo_ (4) { } // derived::derived
+  void a_function (void) const // derived::a_function
+  { 
+    this->base1::a_function ();
+    this->base2::a_function ();
+  }
+
+  protected:
+  int foo_;
+};
+
+int
+main (int argc, char* argv[]) // main
+{ // main
+  derived d;
+  void (derived::*pfunc) (void) const = &derived::a_function;
+  (d.*pfunc) ();
+
+  base a (1), b (3), c (8);
+  (void) a.overload ();
+  (void) a.overload (static_cast<int> (0));
+  (void) a.overload (static_cast<short> (0));
+  (void) a.overload (static_cast<long> (0));
+  (void) a.overload (static_cast<char*> (0));
+  (void) a.overload (a);
+
+  int r;
+  r = b + c;
+  ++a;
+  a += b;
+  r = b - c;
+  --a;
+  a -= b;
+  r = b * c;
+  a *= b;
+  r = b / c;
+  a /= b;
+  r = b % c;
+  a %= b;
+  bool x = (b < c);
+  x = (b <= c);
+  x = (b > c);
+  x = (b >= c);
+  x = (b != c);
+  x = (b == c);
+  x = (!b);
+  x = (b && c);
+  x = (b || c);
+  r = b << 2;
+  a <<= 1;
+  r = b >> 2;
+  a >>= 1;
+  r = ~b;
+  r = b & c;
+  a &= c;
+  r = b | c;
+  a |= c;
+  r = b ^ c;
+  a ^= c;
+  a = c;
+  a ();
+  int i = a[3];
+  derived* f = new derived ();
+  derived* g = new derived[3];
+  delete f;
+  delete[] g;
+  a->overload ();
+  r = a->*b;
+
+  tclass<char> char_tclass;
+  tclass<int> int_tclass;
+  tclass<short> short_tclass;
+  tclass<long> long_tclass;
+  tclass<base> base_tclass;
+  char_tclass.do_something ();
+  int_tclass.do_something ();
+  short_tclass.do_something ();
+  long_tclass.do_something ();
+  base_tclass.do_something ();
+
+  flubber<int, int, int, int, int> ();
+  flubber<int, int, int, int, short> ();
+  flubber<int, int, int, int, long> ();
+  flubber<int, int, int, int, char> ();
+  flubber<int, int, int, short, int> ();
+  flubber<int, int, int, short, short> ();
+  flubber<int, int, int, short, long> ();
+  flubber<int, int, int, short, char> ();
+  flubber<int, int, int, long, int> ();
+  flubber<int, int, int, long, short> ();
+  flubber<int, int, int, long, long> ();
+  flubber<int, int, int, long, char> ();
+  flubber<int, int, int, char, int> ();
+  flubber<int, int, int, char, short> ();
+  flubber<int, int, int, char, long> ();
+  flubber<int, int, int, char, char> ();
+  flubber<int, int, short, int, int> ();
+  flubber<int, int, short, int, short> ();
+  flubber<int, int, short, int, long> ();
+  flubber<int, int, short, int, char> ();
+  flubber<int, int, short, short, int> ();
+  flubber<short, int, short, int, short> ();
+  flubber<long, short, long, short, long> ();
+
+  policy1 p1 (1);
+  p1.function ();
+  policy2 p2 (2);
+  p2.function ();
+  policy3 p3 (3);
+  p3.function ();
+  policy4 p4 (4);
+  p4.function ();
+
+  policyd1 pd1 (5);
+  pd1.function ();
+  policyd2 pd2 (6);
+  pd2.function ();
+  policyd3 pd3 (7);
+  pd3.function ();
+  policyd4 pd4 (d);
+  pd4.function ();
+  policyd5 pd5 (int_tclass);
+  pd5.function ();
+
+  base1 b1 (3);
+
+  r = a;
+  char* str = a;
+  fluff* flp = a;
+  fluff** flpp = a;
+}
+

[-- Attachment #3: dwarf2_physname-2.patch --]
[-- Type: text/plain, Size: 44691 bytes --]

Index: c-typeprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-typeprint.c,v
retrieving revision 1.50
diff -u -p -r1.50 c-typeprint.c
--- c-typeprint.c	1 Jan 2010 07:31:30 -0000	1.50
+++ c-typeprint.c	28 Jan 2010 23:05:37 -0000
@@ -32,6 +32,7 @@
 #include "c-lang.h"
 #include "typeprint.h"
 #include "cp-abi.h"
+#include "jv-lang.h"
 
 #include "gdb_string.h"
 #include <errno.h>
@@ -40,8 +41,6 @@ static void cp_type_print_method_args (s
 				       char *varstring, int staticp,
 				       struct ui_file *stream);
 
-static void c_type_print_args (struct type *, struct ui_file *);
-
 static void cp_type_print_derivation_info (struct ui_file *, struct type *);
 
 static void c_type_print_varspec_prefix (struct type *, struct ui_file *, int,
@@ -197,6 +196,23 @@ cp_type_print_method_args (struct type *
     fprintf_filtered (stream, "void");
 
   fprintf_filtered (stream, ")");
+
+  /* For non-static methods, read qualifiers from the type of
+     THIS.  */
+  if (!staticp)
+    {
+      struct type *domain;
+
+      gdb_assert (nargs > 0);
+      gdb_assert (TYPE_CODE (args[0].type) == TYPE_CODE_PTR);
+      domain = TYPE_TARGET_TYPE (args[0].type);
+
+      if (TYPE_CONST (domain))
+	fprintf_filtered (stream, " const");
+
+      if (TYPE_VOLATILE (domain))
+	fprintf_filtered (stream, " volatile");
+    }
 }
 
 
@@ -353,10 +369,14 @@ c_type_print_modifier (struct type *type
 
 /* Print out the arguments of TYPE, which should have TYPE_CODE_METHOD
    or TYPE_CODE_FUNC, to STREAM.  Artificial arguments, such as "this"
-   in non-static methods, are displayed.  */
+   in non-static methods, are displayed if SHOW_ARTIFICIAL is
+   non-zero. LANGUAGE is the language in which TYPE was defined.  This is
+   a necessary evil since this code is used by the C, C++, and Java
+   backends. */
 
-static void
-c_type_print_args (struct type *type, struct ui_file *stream)
+void
+c_type_print_args (struct type *type, struct ui_file *stream,
+		   int show_artificial, enum language language)
 {
   int i, len;
   struct field *args;
@@ -368,13 +388,19 @@ c_type_print_args (struct type *type, st
 
   for (i = 0; i < TYPE_NFIELDS (type); i++)
     {
+      if (TYPE_FIELD_ARTIFICIAL (type, i) && !show_artificial)
+	continue;
+
       if (printed_any)
 	{
 	  fprintf_filtered (stream, ", ");
 	  wrap_here ("    ");
 	}
 
-      c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
+      if (language == language_java)
+	java_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
+      else
+	c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
       printed_any = 1;
     }
 
@@ -591,7 +617,7 @@ c_type_print_varspec_suffix (struct type
       if (passed_a_ptr)
 	fprintf_filtered (stream, ")");
       if (!demangled_args)
-	c_type_print_args (type, stream);
+	c_type_print_args (type, stream, 1, language_c);
       c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show,
 				   passed_a_ptr, 0);
       break;
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.352
diff -u -p -r1.352 dwarf2read.c
--- dwarf2read.c	26 Jan 2010 15:48:25 -0000	1.352
+++ dwarf2read.c	28 Jan 2010 23:05:43 -0000
@@ -48,6 +48,9 @@
 #include "gdbcmd.h"
 #include "block.h"
 #include "addrmap.h"
+#include "typeprint.h"
+#include "jv-lang.h"
+#include "vec.h"
 
 #include <fcntl.h>
 #include "gdb_string.h"
@@ -487,8 +490,7 @@ struct partial_die_info
     unsigned int has_byte_size : 1;
 
     /* The name of this DIE.  Normally the value of DW_AT_name, but
-       sometimes DW_TAG_MIPS_linkage_name or a string computed in some
-       other fashion.  */
+       sometimes a default name for unnamed DIEs.  */
     char *name;
 
     /* The scope to prepend to our children.  This is generally
@@ -677,6 +679,11 @@ struct field_info
     int nfnfields;
   };
 
+/* A vector used during linkage name generation.  */
+typedef struct die_info *die_info_p;
+DEF_VEC_P (die_info_p);
+static VEC(die_info_p) *die_list;
+
 /* One item on the queue of compilation units to read in full symbols
    for.  */
 struct dwarf2_queue_item
@@ -788,7 +795,7 @@ static void scan_partial_symbols (struct
 static void add_partial_symbol (struct partial_die_info *,
 				struct dwarf2_cu *);
 
-static int pdi_needs_namespace (enum dwarf_tag tag);
+static int die_needs_namespace (struct die_info *, struct dwarf2_cu *);
 
 static void add_partial_namespace (struct partial_die_info *pdi,
 				   CORE_ADDR *lowpc, CORE_ADDR *highpc,
@@ -940,6 +947,11 @@ static struct type *tag_type_to_type (st
 
 static struct type *read_type_die (struct die_info *, struct dwarf2_cu *);
 
+static char *physname_prefix (struct die_info *die, struct dwarf2_cu *);
+
+static void physname_prefix_1 (struct ui_file *, struct die_info *,
+			       struct dwarf2_cu *);
+
 static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
 
 static char *typename_concat (struct obstack *,
@@ -984,9 +996,6 @@ static void dwarf2_attach_fn_fields_to_t
 
 static void process_structure_scope (struct die_info *, struct dwarf2_cu *);
 
-static const char *determine_class_name (struct die_info *die,
-					 struct dwarf2_cu *cu);
-
 static void read_common_block (struct die_info *, struct dwarf2_cu *);
 
 static void read_namespace (struct die_info *die, struct dwarf2_cu *);
@@ -1028,7 +1037,7 @@ static gdb_byte *read_full_die (const st
 
 static void process_die (struct die_info *, struct dwarf2_cu *);
 
-static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
+static char *dwarf2_physname (struct die_info *, struct dwarf2_cu *);
 
 static char *dwarf2_canonicalize_name (char *, struct dwarf2_cu *,
 				       struct obstack *);
@@ -2441,12 +2450,9 @@ add_partial_symbol (struct partial_die_i
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  if (pdi_needs_namespace (pdi->tag))
-    {
-      actual_name = partial_die_full_name (pdi, cu);
-      if (actual_name)
-	built_actual_name = 1;
-    }
+  actual_name = partial_die_full_name (pdi, cu);
+  if (actual_name)
+    built_actual_name = 1;
 
   if (actual_name == NULL)
     actual_name = pdi->name;
@@ -2586,34 +2592,17 @@ add_partial_symbol (struct partial_die_i
       break;
     }
 
-  /* Check to see if we should scan the name for possible namespace
-     info.  Only do this if this is C++, if we don't have namespace
-     debugging info in the file, if the psym is of an appropriate type
-     (otherwise we'll have psym == NULL), and if we actually had a
-     mangled name to begin with.  */
-
-  /* FIXME drow/2004-02-22: Why don't we do this for classes, i.e. the
-     cases which do not set PSYM above?  */
-
-  if (cu->language == language_cplus
-      && cu->has_namespace_info == 0
-      && psym != NULL
-      && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
-    cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym),
-					 objfile);
-
   if (built_actual_name)
     xfree (actual_name);
 }
 
-/* Determine whether a die of type TAG living in a C++ class or
-   namespace needs to have the name of the scope prepended to the
-   name listed in the die.  */
+/* Determine whether DIE needs to have the name of the scope prepended
+   to the name listed in the die.  */
 
 static int
-pdi_needs_namespace (enum dwarf_tag tag)
+die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu)
 {
-  switch (tag)
+  switch (die->tag)
     {
     case DW_TAG_namespace:
     case DW_TAG_typedef:
@@ -2623,7 +2612,23 @@ pdi_needs_namespace (enum dwarf_tag tag)
     case DW_TAG_union_type:
     case DW_TAG_enumeration_type:
     case DW_TAG_enumerator:
+    case DW_TAG_subprogram:
+    case DW_TAG_member:
       return 1;
+
+    case DW_TAG_variable:
+      {
+	struct attribute *attr;
+	attr = dwarf2_attr (die, DW_AT_specification, cu);
+	if (attr)
+	  return 1;
+	attr = dwarf2_attr (die, DW_AT_external, cu);
+	if (attr == NULL && die->parent->tag != DW_TAG_namespace)
+	  return 0;
+	return 1;
+      }
+      break;
+
     default:
       return 0;
     }
@@ -2752,27 +2757,6 @@ guess_structure_name (struct partial_die
 
       if (real_pdi->die_parent != NULL)
 	return;
-
-      while (child_pdi != NULL)
-	{
-	  if (child_pdi->tag == DW_TAG_subprogram)
-	    {
-	      char *actual_class_name
-		= language_class_name_from_physname (cu->language_defn,
-						     child_pdi->name);
-	      if (actual_class_name != NULL)
-		{
-		  struct_pdi->name
-		    = obsavestring (actual_class_name,
-				    strlen (actual_class_name),
-				    &cu->comp_unit_obstack);
-		  xfree (actual_class_name);
-		}
-	      break;
-	    }
-
-	  child_pdi = child_pdi->die_sibling;
-	}
     }
 }
 
@@ -3340,37 +3324,52 @@ process_die (struct die_info *die, struc
 /* Return the fully qualified name of DIE, based on its DW_AT_name.
    If scope qualifiers are appropriate they will be added.  The result
    will be allocated on the objfile_obstack, or NULL if the DIE does
-   not have a name.  */
+   not have a name.
+
+   The output string will be canonicalized (if C++/Java). */
 
 static const char *
 dwarf2_full_name (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct attribute *attr;
-  char *prefix, *name;
-  struct ui_file *buf = NULL;
+  char *name;
 
   name = dwarf2_name (die, cu);
-  if (!name)
-    return NULL;
 
   /* These are the only languages we know how to qualify names in.  */
-  if (cu->language != language_cplus
-      && cu->language != language_java)
-    return name;
+  if (name != NULL
+      && (cu->language == language_cplus || cu->language == language_java))
+    {
+      if (die_needs_namespace (die, cu))
+	{
+	  long length;
+	  char *prefix;
+	  struct ui_file *buf;
+
+	  buf = mem_fileopen ();
+	  prefix = determine_prefix (die, cu);
+	  if (*prefix != '\0')
+	    {
+	      char *prefixed_name = typename_concat (NULL, prefix, name, cu);
+	      fputs_unfiltered (prefixed_name, buf);
+	      xfree (prefixed_name);
+	    }
+	  else
+	    fputs_unfiltered (name, buf);
 
-  /* If no prefix is necessary for this type of DIE, return the
-     unqualified name.  The other three tags listed could be handled
-     in pdi_needs_namespace, but that requires broader changes.  */
-  if (!pdi_needs_namespace (die->tag)
-      && die->tag != DW_TAG_subprogram
-      && die->tag != DW_TAG_variable
-      && die->tag != DW_TAG_member)
-    return name;
+	  name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack,
+				       &length);
+	  ui_file_delete (buf);
 
-  prefix = determine_prefix (die, cu);
-  if (*prefix != '\0')
-    name = typename_concat (&cu->objfile->objfile_obstack, prefix,
-			    name, cu);
+	  if (cu->language == language_cplus)
+	    {
+	      char *cname
+		= dwarf2_canonicalize_name (name, cu,
+					    &cu->objfile->objfile_obstack);
+	      if (cname != NULL)
+		name = cname;
+	    }
+	}
+    }
 
   return name;
 }
@@ -3843,7 +3842,7 @@ read_func_scope (struct die_info *die, s
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  name = dwarf2_linkage_name (die, cu);
+  name = dwarf2_name (die, cu);
 
   /* Ignore functions with missing or empty names and functions with
      missing or invalid low and high pc attributes.  */
@@ -4517,7 +4516,7 @@ dwarf2_add_field (struct field_info *fip
 	return;
 
       /* Get physical name.  */
-      physname = dwarf2_linkage_name (die, cu);
+      physname = dwarf2_physname (die, cu);
 
       /* The name is already allocated along with this objfile, so we don't
 	 need to duplicate it for the type.  */
@@ -4679,7 +4678,7 @@ dwarf2_add_member_fn (struct field_info 
     return;
 
   /* Get the mangled name.  */
-  physname = dwarf2_linkage_name (die, cu);
+  physname = dwarf2_physname (die, cu);
 
   /* Look up member function name in fieldlist.  */
   for (i = 0; i < fip->nfnfields; i++)
@@ -4986,14 +4985,18 @@ read_structure_type (struct die_info *di
       if (cu->language == language_cplus
 	  || cu->language == language_java)
 	{
-	  const char *new_prefix = determine_class_name (die, cu);
-	  TYPE_TAG_NAME (type) = (char *) new_prefix;
+	  TYPE_TAG_NAME (type) = (char *) dwarf2_full_name (die, cu);
+	  if (die->tag == DW_TAG_structure_type
+	      || die->tag == DW_TAG_class_type)
+	    TYPE_NAME (type) = TYPE_TAG_NAME (type);
 	}
       else
 	{
 	  /* The name is already allocated along with this objfile, so
 	     we don't need to duplicate it for the type.  */
-	  TYPE_TAG_NAME (type) = name;
+	  TYPE_TAG_NAME (type) = (char *) name;
+	  if (die->tag == DW_TAG_class_type)
+	    TYPE_NAME (type) = TYPE_TAG_NAME (type);
 	}
     }
 
@@ -5236,51 +5239,6 @@ read_enumeration_type (struct die_info *
   return set_die_type (die, type, cu);
 }
 
-/* Determine the name of the type represented by DIE, which should be
-   a named C++ or Java compound type.  Return the name in question,
-   allocated on the objfile obstack.  */
-
-static const char *
-determine_class_name (struct die_info *die, struct dwarf2_cu *cu)
-{
-  const char *new_prefix = NULL;
-
-  /* If we don't have namespace debug info, guess the name by trying
-     to demangle the names of members, just like we did in
-     guess_structure_name.  */
-  if (!processing_has_namespace_info)
-    {
-      struct die_info *child;
-
-      for (child = die->child;
-	   child != NULL && child->tag != 0;
-	   child = sibling_die (child))
-	{
-	  if (child->tag == DW_TAG_subprogram)
-	    {
-	      char *phys_prefix
-		= language_class_name_from_physname (cu->language_defn,
-						     dwarf2_linkage_name
-						     (child, cu));
-
-	      if (phys_prefix != NULL)
-		{
-		  new_prefix
-		    = obsavestring (phys_prefix, strlen (phys_prefix),
-				    &cu->objfile->objfile_obstack);
-		  xfree (phys_prefix);
-		  break;
-		}
-	    }
-	}
-    }
-
-  if (new_prefix == NULL)
-    new_prefix = dwarf2_full_name (die, cu);
-
-  return new_prefix;
-}
-
 /* Given a pointer to a die which begins an enumeration, process all
    the dies that define the members of the enumeration, and create the
    symbol for the enumeration type.
@@ -6764,7 +6722,8 @@ read_partial_die (struct partial_die_inf
 	    }
 	  break;
 	case DW_AT_MIPS_linkage_name:
-	  part_die->name = DW_STRING (&attr);
+	  if (cu->language == language_ada)
+	    part_die->name = DW_STRING (&attr);
 	  break;
 	case DW_AT_low_pc:
 	  has_low_pc_attr = 1;
@@ -8329,13 +8288,11 @@ new_symbol (struct die_info *die, struct
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  if (die->tag != DW_TAG_namespace)
-    name = dwarf2_linkage_name (die, cu);
-  else
-    name = TYPE_NAME (type);
-
+  name = dwarf2_name (die, cu);
   if (name)
     {
+      const char *linkagename;
+
       sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
 					     sizeof (struct symbol));
       OBJSTAT (objfile, n_syms++);
@@ -8343,7 +8300,8 @@ new_symbol (struct die_info *die, struct
 
       /* Cache this symbol's name and the name's demangled form (if any).  */
       SYMBOL_LANGUAGE (sym) = cu->language;
-      SYMBOL_SET_NAMES (sym, name, strlen (name), 0, objfile);
+      linkagename = dwarf2_physname (die, cu);
+      SYMBOL_SET_NAMES (sym, linkagename, strlen (linkagename), 0, objfile);
 
       /* Default assumptions.
          Use the passed type or decode it from the die.  */
@@ -8617,8 +8575,7 @@ new_symbol (struct die_info *die, struct
       /* For the benefit of old versions of GCC, check for anonymous
 	 namespaces based on the demangled name.  */
       if (!processing_has_namespace_info
-	  && cu->language == language_cplus
-	  && dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu) != NULL)
+	  && cu->language == language_cplus)
 	cp_scan_for_anonymous_namespaces (sym);
     }
   return (sym);
@@ -9021,6 +8978,96 @@ determine_prefix (struct die_info *die, 
       }
 }
 
+/* Determines the prefix for a symbol's physname.  Unlike determine_prefix,
+   this method does not simply look at the DIE's immediate parent.
+   It will compute the symbol's physname by scanning through all parent
+   DIEs until it gets to the compilation unit's DIE.  */
+
+static char *
+physname_prefix (struct die_info *die, struct dwarf2_cu *cu)
+{
+  long length;
+  struct ui_file *buf;
+  struct die_info *d, *spec_die;
+  struct dwarf2_cu *spec_cu;
+  char *name;
+
+  /* Construct a stack containing all of the DIE's parents.  Caution
+     must be observed for dealing with DW_AT_specification. */
+  spec_cu = cu;
+  spec_die = die_specification (die, &spec_cu);
+  if (spec_die != NULL)
+    d = spec_die->parent;
+  else
+    d = die->parent;
+  while (d != NULL && d->tag != DW_TAG_compile_unit)
+    {
+      struct attribute *attr;
+
+      spec_die = die_specification (d, &spec_cu);
+      if (spec_die != NULL)
+	d = spec_die;
+
+      VEC_quick_push (die_info_p, die_list, d);
+      d = d->parent;
+    }
+
+  /* Now pop all the elements, printing their names as we go.  */
+  buf = mem_fileopen ();
+  while (!VEC_empty (die_info_p, die_list))
+    {
+      d = VEC_pop (die_info_p, die_list);
+      physname_prefix_1 (buf, d, cu);
+
+      if (!VEC_empty (die_info_p, die_list))
+	{
+	  if (cu->language == language_cplus)
+	    fputs_unfiltered ("::", buf);
+	  else
+	    fputs_unfiltered (".", buf);
+	}
+    }
+
+  name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack, &length);
+  ui_file_delete (buf);
+  return name;
+}
+
+static void
+physname_prefix_1 (struct ui_file *buf, struct die_info *die,
+		   struct dwarf2_cu *cu)
+{
+  const char *name = NULL;
+  gdb_assert (buf != NULL);
+
+  if (die != NULL)
+    {
+      switch (die->tag)
+	{
+	case DW_TAG_namespace:
+	  name = dwarf2_name (die, cu);
+	  if (name == NULL)
+	    name = "(anonymous namespace)";
+	  break;
+
+	case DW_TAG_class_type:
+	case DW_TAG_structure_type:
+	case DW_TAG_union_type:
+	case DW_TAG_enumeration_type:
+	case DW_TAG_interface_type:
+	case DW_TAG_subprogram:
+	  name = dwarf2_name (die, cu);
+	  break;
+
+	default:
+	  break;
+	}
+    }
+
+  if (name != NULL)
+    fputs_unfiltered (name, buf);
+}
+
 /* Return a newly-allocated string formed by concatenating PREFIX and
    SUFFIX with appropriate separator.  If PREFIX or SUFFIX is NULL or empty, then
    simply copy the SUFFIX or PREFIX, respectively.  If OBS is non-null,
@@ -9070,17 +9117,78 @@ sibling_die (struct die_info *die)
   return die->sibling;
 }
 
-/* Get linkage name of a die, return NULL if not found.  */
+/* Construct a physname for the given DIE in CU. */
 
 static char *
-dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
+dwarf2_physname (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
+  char *name;
+
+  name = dwarf2_name (die, cu);
+
+  /* These are the only languages we know how to qualify names in.  */
+  if (cu->language != language_cplus
+      && cu->language != language_java)
+    return name;
+
+  if (die_needs_namespace (die, cu))
+    {
+      long length;
+      char *prefix;
+      struct ui_file *buf;
+
+      prefix = physname_prefix (die, cu);
+      buf = mem_fileopen ();
+      if (*prefix != '\0')
+	{
+	  char *prefixed_name = typename_concat (NULL, prefix, name, cu);
+	  fputs_unfiltered (prefixed_name, buf);
+	  xfree (prefixed_name);
+	}
+      else
+	fputs_unfiltered (name ? name : "", buf);
+
+      /* For Java and C++ methods, append formal parameter type
+	 information. */
+      if ((cu->language == language_cplus || cu->language == language_java)
+	  && die->tag == DW_TAG_subprogram)
+	{
+	  struct type *type = read_type_die (die, cu);
 
-  attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
-  if (attr && DW_STRING (attr))
-    return DW_STRING (attr);
-  return dwarf2_name (die, cu);
+	  c_type_print_args (type, buf, 0, cu->language);
+
+	  if (cu->language == language_java)
+	    {
+	      /* For java, we must append the return type to method names. */
+	      if (die->tag == DW_TAG_subprogram)
+		java_print_type (TYPE_TARGET_TYPE (type), "", buf, 0, 0);
+	    }
+	  else if (cu->language == language_cplus)
+	    {
+	      /* c_type_print_args adds argument types, but it does
+		 not add any necessary "const". */
+	      if (TYPE_NFIELDS (type) > 0 && TYPE_FIELD_ARTIFICIAL (type, 0)
+		  && TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0))))
+		fputs_unfiltered (" const", buf);
+	    }
+	}
+
+      name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack,
+				   &length);
+      ui_file_delete (buf);
+
+      if (cu->language == language_cplus)
+	{
+	  char *cname
+	    = dwarf2_canonicalize_name (name, cu,
+					&cu->objfile->objfile_obstack);
+	  if (cname != NULL)
+	    name = cname;
+	}
+    }
+
+  return name;
 }
 
 /* Get name of a die, return NULL if not found.  */
@@ -11977,6 +12085,7 @@ void _initialize_dwarf2_read (void);
 void
 _initialize_dwarf2_read (void)
 {
+  die_list = VEC_alloc (die_info_p, 32);
   dwarf2_objfile_data_key
     = register_objfile_data_with_cleanup (NULL, dwarf2_per_objfile_free);
 
Index: gnu-v3-abi.c
===================================================================
RCS file: /cvs/src/src/gdb/gnu-v3-abi.c,v
retrieving revision 1.58
diff -u -p -r1.58 gnu-v3-abi.c
--- gnu-v3-abi.c	1 Jan 2010 07:31:32 -0000	1.58
+++ gnu-v3-abi.c	28 Jan 2010 23:05:46 -0000
@@ -26,6 +26,7 @@
 #include "demangle.h"
 #include "objfiles.h"
 #include "valprint.h"
+#include "c-lang.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
@@ -456,10 +457,8 @@ gnuv3_find_method_in (struct type *domai
 		      LONGEST adjustment)
 {
   int i;
-  const char *physname;
 
   /* Search this class first.  */
-  physname = NULL;
   if (adjustment == 0)
     {
       int len;
@@ -587,15 +586,24 @@ gnuv3_print_method_ptr (const gdb_byte *
 	{
 	  char *demangled_name = cplus_demangle (physname,
 						 DMGL_ANSI | DMGL_PARAMS);
-	  if (demangled_name != NULL)
+	  fprintf_filtered (stream, "&virtual ");
+	  if (demangled_name == NULL)
+	    fputs_filtered (physname, stream);
+	  else
 	    {
-	      fprintf_filtered (stream, "&virtual ");
 	      fputs_filtered (demangled_name, stream);
 	      xfree (demangled_name);
-	      return;
 	    }
+	  return;
 	}
     }
+  else if (ptr_value != 0)
+    {
+      /* Found a non-virtual function: print out the type.  */
+      fputs_filtered ("(", stream);
+      c_print_type (type, "", stream, -1, 0);
+      fputs_filtered (") ", stream);
+    }
 
   /* We didn't find it; print the raw data.  */
   if (vbit)
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.224
diff -u -p -r1.224 symtab.c
--- symtab.c	26 Jan 2010 15:48:25 -0000	1.224
+++ symtab.c	28 Jan 2010 23:05:50 -0000
@@ -498,7 +495,7 @@ symbol_find_demangled_name (struct gener
       || gsymbol->language == language_auto)
     {
       demangled =
-        cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
+        cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
       if (demangled != NULL)
 	{
 	  gsymbol->language = language_cplus;
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.146
diff -u -p -r1.146 symtab.h
--- symtab.h	27 Jan 2010 00:15:59 -0000	1.146
+++ symtab.h	28 Jan 2010 23:05:53 -0000
@@ -172,9 +172,6 @@ extern CORE_ADDR symbol_overlayed_addres
 #define SYMBOL_SECTION(symbol)		(symbol)->ginfo.section
 #define SYMBOL_OBJ_SECTION(symbol)	(symbol)->ginfo.obj_section
 
-#define SYMBOL_CPLUS_DEMANGLED_NAME(symbol)	\
-  (symbol)->ginfo.language_specific.cplus_specific.demangled_name
-
 /* Initializes the language dependent portion of a symbol
    depending upon the language for the symbol. */
 #define SYMBOL_INIT_LANGUAGE_SPECIFIC(symbol,language) \
@@ -994,7 +991,6 @@ extern struct symbol *lookup_symbol (con
    that can't think of anything better to do.  */
 
 extern struct symbol *basic_lookup_symbol_nonlocal (const char *,
-						    const char *,
 						    const struct block *,
 						    const domain_enum);
 
@@ -1005,7 +1001,6 @@ extern struct symbol *basic_lookup_symbo
    is one; do nothing if BLOCK is NULL or a global block.  */
 
 extern struct symbol *lookup_symbol_static (const char *name,
-					    const char *linkage_name,
 					    const struct block *block,
 					    const domain_enum domain);
 
@@ -1013,7 +1008,6 @@ extern struct symbol *lookup_symbol_stat
    necessary).  */
 
 extern struct symbol *lookup_symbol_global (const char *name,
-					    const char *linkage_name,
 					    const struct block *block,
 					    const domain_enum domain);
 
@@ -1022,21 +1016,18 @@ extern struct symbol *lookup_symbol_glob
    will fix up the symbol if necessary.  */
 
 extern struct symbol *lookup_symbol_aux_block (const char *name,
-					       const char *linkage_name,
 					       const struct block *block,
 					       const domain_enum domain);
 
 /* Lookup a partial symbol.  */
 
 extern struct partial_symbol *lookup_partial_symbol (struct partial_symtab *,
-						     const char *,
 						     const char *, int,
 						     domain_enum);
 
 /* lookup a symbol by name, within a specified block */
 
 extern struct symbol *lookup_block_symbol (const struct block *, const char *,
-					   const char *,
 					   const domain_enum);
 
 /* lookup a [struct, union, enum] by name, within a specified block */
@@ -1372,7 +1363,6 @@ extern /*const */ char *main_name (void)
 /* Check global symbols in objfile.  */
 struct symbol *lookup_global_symbol_from_objfile (const struct objfile *objfile,
 						  const char *name,
-						  const char *linkage_name,
 						  const domain_enum domain);
 
 extern struct symtabs_and_lines
Index: typeprint.h
===================================================================
RCS file: /cvs/src/src/gdb/typeprint.h,v
retrieving revision 1.9
diff -u -p -r1.9 typeprint.h
--- typeprint.h	1 Jan 2010 07:31:43 -0000	1.9
+++ typeprint.h	28 Jan 2010 23:05:56 -0000
@@ -20,10 +20,13 @@
 #ifndef TYPEPRINT_H
 #define TYPEPRINT_H
 
+enum language;
 struct ui_file;
 
 void print_type_scalar (struct type * type, LONGEST, struct ui_file *);
 
 void c_type_print_varspec_suffix (struct type *, struct ui_file *, int,
 				  int, int);
+
+void c_type_print_args (struct type *, struct ui_file *, int, enum language);
 #endif
Index: ui-file.c
===================================================================
RCS file: /cvs/src/src/gdb/ui-file.c,v
retrieving revision 1.20
diff -u -p -r1.20 ui-file.c
--- ui-file.c	1 Jan 2010 07:31:43 -0000	1.20
+++ ui-file.c	28 Jan 2010 23:06:00 -0000
@@ -22,6 +22,7 @@
 
 #include "defs.h"
 #include "ui-file.h"
+#include "gdb_obstack.h"
 #include "gdb_string.h"
 #include "gdb_select.h"
 
@@ -264,7 +265,7 @@ set_ui_file_data (struct ui_file *file, 
 }
 
 /* ui_file utility function for converting a ``struct ui_file'' into
-   a memory buffer''. */
+   a memory buffer. */
 
 struct accumulated_ui_file
 {
@@ -298,6 +299,23 @@ ui_file_xstrdup (struct ui_file *file, l
     *length = acc.length;
   return acc.buffer;
 }
+
+static void
+do_ui_file_obsavestring (void *context, const char *buffer, long length)
+{
+  struct obstack *obstack = (struct obstack *) context;
+  obstack_grow (obstack, buffer, length);
+}
+
+char *
+ui_file_obsavestring (struct ui_file *file, struct obstack *obstack,
+		      long *length)
+{
+  ui_file_put (file, do_ui_file_obsavestring, obstack);
+  *length = obstack_object_size (obstack);
+  obstack_1grow (obstack, '\0');
+  return obstack_finish (obstack);
+}
 \f
 /* A pure memory based ``struct ui_file'' that can be used an output
    buffer. The buffers accumulated contents are available via
Index: ui-file.h
===================================================================
RCS file: /cvs/src/src/gdb/ui-file.h,v
retrieving revision 1.11
diff -u -p -r1.11 ui-file.h
--- ui-file.h	1 Jan 2010 07:31:43 -0000	1.11
+++ ui-file.h	28 Jan 2010 23:06:03 -0000
@@ -20,6 +20,7 @@
 #ifndef UI_FILE_H
 #define UI_FILE_H
 
+struct obstack;
 struct ui_file;
 
 /* Create a generic ui_file object with null methods. */
@@ -78,7 +79,10 @@ extern void ui_file_put (struct ui_file 
    minus that appended NUL. */
 extern char *ui_file_xstrdup (struct ui_file *file, long *length);
 
-
+/* Similar to ui_file_xstrdup, but return a new string allocated on
+   OBSTACK.  */
+extern char *ui_file_obsavestring (struct ui_file *file,
+				   struct obstack *obstack, long *length);
 
 extern long ui_file_read (struct ui_file *file, char *buf, long length_buf);
 
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.233
diff -u -p -r1.233 valops.c
--- valops.c	26 Jan 2010 16:47:34 -0000	1.233
+++ valops.c	28 Jan 2010 23:06:09 -0000
@@ -2328,12 +2328,25 @@ find_overload_match (struct type **arg_t
   if (method)
     {
       gdb_assert (obj);
+
+      /* OBJ may be a pointer value rather than the object itself.  */
+      obj = coerce_ref (obj);
+      while (TYPE_CODE (check_typedef (value_type (obj))) == TYPE_CODE_PTR)
+	obj = coerce_ref (value_ind (obj));
       obj_type_name = TYPE_NAME (value_type (obj));
-      /* Hack: evaluate_subexp_standard often passes in a pointer
-         value rather than the object itself, so try again.  */
-      if ((!obj_type_name || !*obj_type_name) 
-	  && (TYPE_CODE (value_type (obj)) == TYPE_CODE_PTR))
-	obj_type_name = TYPE_NAME (TYPE_TARGET_TYPE (value_type (obj)));
+
+      /* First check whether this is a data member, e.g. a pointer to
+	 a function.  */
+      if (TYPE_CODE (check_typedef (value_type (obj))) == TYPE_CODE_STRUCT)
+	{
+	  *valp = search_struct_field (name, obj, 0,
+				       check_typedef (value_type (obj)), 0);
+	  if (*valp)
+	    {
+	      *staticp = 1;
+	      return 0;
+	    }
+	}
 
       fns_ptr = value_find_oload_method_list (&temp, name, 
 					      0, &num_fns, 
@@ -2353,16 +2366,29 @@ find_overload_match (struct type **arg_t
     }
   else
     {
-      const char *qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym);
+      const char *qualified_name = SYMBOL_NATURAL_NAME (fsym);
+
+      /* If we have a function with a C++ name, try to extract just
+	 the function part.  Do not try this for non-functions (e.g.
+	 function pointers).  */
+      if (qualified_name
+	  && TYPE_CODE (check_typedef (SYMBOL_TYPE (fsym))) == TYPE_CODE_FUNC)
+	{
+	  func_name = cp_func_name (qualified_name);
+
+	  /* If cp_func_name did not remove anything, the name of the
+	     symbol did not include scope or argument types - it was
+	     probably a C-style function.  */
+	  if (func_name && strcmp (func_name, qualified_name) == 0)
+	    {
+	      xfree (func_name);
+	      func_name = NULL;
+	    }
+	}
 
-      /* If we have a C++ name, try to extract just the function
-	 part.  */
-      if (qualified_name)
-	func_name = cp_func_name (qualified_name);
-
-      /* If there was no C++ name, this must be a C-style function.
-	 Just return the same symbol.  Do the same if cp_func_name
-	 fails for some reason.  */
+      /* If there was no C++ name, this must be a C-style function or
+	 not a function at all.  Just return the same symbol.  Do the
+	 same if cp_func_name fails for some reason.  */
       if (func_name == NULL)
         {
 	  *symp = fsym;
Index: linespec.c
===================================================================
RCS file: /cvs/src/src/gdb/linespec.c,v
retrieving revision 1.95
diff -u -p -r1.95 linespec.c
--- linespec.c	12 Jan 2010 05:48:56 -0000	1.95
+++ linespec.c	28 Jan 2010 23:06:13 -0000
@@ -40,6 +40,7 @@
 #include "interps.h"
 #include "mi/mi-cmds.h"
 #include "target.h"
+#include "arch-utils.h"
 
 /* We share this one with symtab.c, but it is not exported widely. */
 
@@ -50,8 +51,6 @@ extern char *operator_chars (char *, cha
 static void initialize_defaults (struct symtab **default_symtab,
 				 int *default_line);
 
-static void set_flags (char *arg, int *is_quoted, char **paren_pointer);
-
 static struct symtabs_and_lines decode_indirect (char **argptr);
 
 static char *locate_first_half (char **argptr, int *is_quote_enclosed);
@@ -628,6 +627,37 @@ See set/show multiple-symbol."));
   discard_cleanups (old_chain);
   return return_values;
 }
+
+/* A helper function for decode_line_1 and friends which skips P
+   past any method overload information at the beginning of P, e.g.,
+   "(const struct foo *)".
+
+   This function assumes that P has already been validated to contain
+   overload information, and it will assert if *P != '('.  */
+static char *
+find_method_overload_end (char *p)
+{
+  int depth = 0;
+
+  gdb_assert (*p == '(');
+
+  while (*p)
+    {
+      if (*p == '(')
+	++depth;
+      else if (*p == ')')
+	{
+	  if (--depth == 0)
+	    {
+	      ++p;
+	      break;
+	    }
+	}
+      ++p;
+    }
+
+  return p;
+}
 \f
 /* The parser of linespec itself. */
 
@@ -688,9 +718,6 @@ decode_line_1 (char **argptr, int funfir
   struct symtab *file_symtab = NULL;
 
   char *copy;
-  /* This is NULL if there are no parens in *ARGPTR, or a pointer to
-     the closing parenthesis if there are parens.  */
-  char *paren_pointer;
   /* This says whether or not something in *ARGPTR is quoted with
      completer_quotes (i.e. with single quotes).  */
   int is_quoted;
@@ -711,12 +738,9 @@ decode_line_1 (char **argptr, int funfir
   if (**argptr == '*')
     return decode_indirect (argptr);
 
-  /* Set various flags.  'paren_pointer' is important for overload
-     checking, where we allow things like:
-        (gdb) break c::f(int)
-  */
-
-  set_flags (*argptr, &is_quoted, &paren_pointer);
+  is_quoted = (*argptr
+	       && strchr (get_gdb_completer_quote_characters (),
+			  **argptr) != NULL);
 
   /* Check to see if it's a multipart linespec (with colons or
      periods).  */
@@ -732,10 +756,7 @@ decode_line_1 (char **argptr, int funfir
   /* Check if this is an Objective-C method (anything that starts with
      a '+' or '-' and a '[').  */
   if (is_objc_method_format (p))
-    {
-      is_objc_method = 1;
-      paren_pointer  = NULL; /* Just a category name.  Ignore it.  */
-    }
+    is_objc_method = 1;
 
   /* Check if the symbol could be an Objective-C selector.  */
 
@@ -749,7 +770,7 @@ decode_line_1 (char **argptr, int funfir
 
   /* Does it look like there actually were two parts?  */
 
-  if ((p[0] == ':' || p[0] == '.') && paren_pointer == NULL)
+  if (p[0] == ':' || p[0] == '.')
     {
       if (is_quoted)
 	*argptr = *argptr + 1;
@@ -762,48 +783,31 @@ decode_line_1 (char **argptr, int funfir
 	 can return now. */
 	
       if (p[0] == '.' || p[1] == ':')
-	return decode_compound (argptr, funfirstline, canonical,
-				saved_arg, p, not_found_ptr);
+	{
+	  struct symtabs_and_lines values;
+
+	  if (is_quote_enclosed)
+	    ++saved_arg;
+	  values = decode_compound (argptr, funfirstline, canonical,
+				    saved_arg, p, not_found_ptr);
+	  if (is_quoted && **argptr == '\'')
+	    *argptr = *argptr + 1;
+	  return values;
+	}
 
       /* No, the first part is a filename; set file_symtab to be that file's
 	 symtab.  Also, move argptr past the filename.  */
 
       file_symtab = symtab_from_filename (argptr, p, is_quote_enclosed, 
 		      			  not_found_ptr);
-    }
-#if 0
-  /* No one really seems to know why this was added. It certainly
-     breaks the command line, though, whenever the passed
-     name is of the form ClassName::Method. This bit of code
-     singles out the class name, and if funfirstline is set (for
-     example, you are setting a breakpoint at this function),
-     you get an error. This did not occur with earlier
-     verions, so I am ifdef'ing this out. 3/29/99 */
-  else
-    {
-      /* Check if what we have till now is a symbol name */
-
-      /* We may be looking at a template instantiation such
-         as "foo<int>".  Check here whether we know about it,
-         instead of falling through to the code below which
-         handles ordinary function names, because that code
-         doesn't like seeing '<' and '>' in a name -- the
-         skip_quoted call doesn't go past them.  So see if we
-         can figure it out right now. */
-
-      copy = (char *) alloca (p - *argptr + 1);
-      memcpy (copy, *argptr, p - *argptr);
-      copy[p - *argptr] = '\000';
-      sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0);
-      if (sym)
+      if (file_symtab != NULL)
 	{
-	  *argptr = (*p == '\'') ? p + 1 : p;
-	  return symbol_found (funfirstline, canonical, copy, sym, NULL);
+	  /* Double-check if the remainder of the argument is quoted.
+	     The rbreak command uses syntax like this.  */
+	  if (**argptr == '\'')
+	    is_quoted = 1;
 	}
-      /* Otherwise fall out from here and go to file/line spec
-         processing, etc. */
     }
-#endif
 
   /* file_symtab is specified file's symtab, or 0 if no file specified.
      arg no longer contains the file name.  */
@@ -838,10 +842,6 @@ decode_line_1 (char **argptr, int funfir
       /* allow word separators in method names for Obj-C */
       p = skip_quoted_chars (*argptr, NULL, "");
     }
-  else if (paren_pointer != NULL)
-    {
-      p = paren_pointer + 1;
-    }
   else
     {
       p = skip_quoted (*argptr);
@@ -851,6 +851,14 @@ decode_line_1 (char **argptr, int funfir
   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;
+
   copy = (char *) alloca (p - *argptr + 1);
   memcpy (copy, *argptr, p - *argptr);
   copy[p - *argptr] = '\0';
@@ -926,44 +934,6 @@ initialize_defaults (struct symtab **def
     }
 }
 
-static void
-set_flags (char *arg, int *is_quoted, char **paren_pointer)
-{
-  char *ii;
-  int has_if = 0;
-
-  /* 'has_if' is for the syntax:
-        (gdb) break foo if (a==b)
-  */
-  if ((ii = strstr (arg, " if ")) != NULL ||
-      (ii = strstr (arg, "\tif ")) != NULL ||
-      (ii = strstr (arg, " if\t")) != NULL ||
-      (ii = strstr (arg, "\tif\t")) != NULL ||
-      (ii = strstr (arg, " if(")) != NULL ||
-      (ii = strstr (arg, "\tif( ")) != NULL)
-    has_if = 1;
-  /* Temporarily zap out "if (condition)" to not confuse the
-     parenthesis-checking code below.  This is undone below. Do not
-     change ii!!  */
-  if (has_if)
-    {
-      *ii = '\0';
-    }
-
-  *is_quoted = (*arg
-		&& strchr (get_gdb_completer_quote_characters (),
-			   *arg) != NULL);
-
-  *paren_pointer = strchr (arg, '(');
-  if (*paren_pointer != NULL)
-    *paren_pointer = strrchr (*paren_pointer, ')');
-
-  /* Now that we're safely past the paren_pointer check, put back " if
-     (condition)" so outer layers can see it.  */
-  if (has_if)
-    *ii = ' ';
-}
-
 \f
 
 /* Decode arg of the form *PC.  */
@@ -1063,8 +1033,9 @@ locate_first_half (char **argptr, int *i
       if (p[0] == '.' && strchr (p, ':') == NULL)
 	{
 	  /* Java qualified method.  Find the *last* '.', since the
-	     others are package qualifiers.  */
-	  for (p1 = p; *p1; p1++)
+	     others are package qualifiers.  Stop at any open parenthesis
+	     which might provide overload information.  */
+	  for (p1 = p; *p1 && *p1 != '('; p1++)
 	    {
 	      if (*p1 == '.')
 		p = p1;
@@ -1216,6 +1187,7 @@ decode_compound (char **argptr, int funf
   struct symbol *sym_class;
   struct symbol **sym_arr;
   struct type *t;
+  char *saved_java_argptr = NULL;
 
   /* First check for "global" namespace specification, of the form
      "::foo".  If found, skip over the colons and jump to normal
@@ -1264,7 +1236,8 @@ 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] != '\''))
+      while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\'')
+	     && (*p != '('))
 	{
 	  if (current_language->la_language == language_cplus)
 	    p += cp_validate_operator (p);
@@ -1342,8 +1315,10 @@ decode_compound (char **argptr, int funf
       else
 	{
 	  /* At this point argptr->"fun".  */
+	  char *a;
 	  p = *argptr;
-	  while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':')
+	  while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':'
+		 && *p != '(')
 	    p++;
 	  /* At this point p->"".  String ended.  */
 	  /* Nope, C++ operators could have spaces in them
@@ -1355,6 +1330,42 @@ decode_compound (char **argptr, int funf
 	      /* The above loop has already swallowed "operator".  */
 	      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;
+
+	  /* Java may append typenames,  so assume that if there is
+	     anything else left in *argptr, it must be a typename.  */
+	  if (*p && current_language->la_language == language_java)
+	    {
+	      struct type *type;
+	      p2 = p;
+	      while (*p2)
+		++p2;
+	      copy = (char *) alloca (p2 - p + 1);
+	      memcpy (copy, p, p2 - p);
+	      copy[p2 - p] = '\0';
+	      type = lookup_typename (current_language, get_current_arch (),
+				      copy, NULL, 1);
+	      if (type != NULL)
+		{
+		  /* Save the location of this just in case this
+		     method/type combination isn't actually defined.
+		     It will be checked later.  */
+		  saved_java_argptr = p;
+		  p = p2;
+		}
+	    }
 	}
 
       /* Allocate our own copy of the substring between argptr and
@@ -1383,9 +1394,26 @@ decode_compound (char **argptr, int funf
 	 here, we return. If not, and we are at the and of the string,
 	 we'll lookup the whole string in the symbol tables.  */
 
-      return find_method (funfirstline, canonical, saved_arg,
-			  copy, t, sym_class, not_found_ptr);
-
+      values = find_method (funfirstline, canonical, saved_arg,
+			    copy, t, sym_class, not_found_ptr);
+      if (saved_java_argptr != NULL && values.nelts == 1)
+	{
+	  /* The user specified a specific return type for a java method.
+	     Double-check that it really is the one the user specified.
+	     [This is a necessary evil because strcmp_iw_ordered stops
+	     comparisons too prematurely.]  */
+	  sym = find_pc_sect_function (values.sals[0].pc,
+				       values.sals[0].section);
+	  /* We just found a SAL, we had better be able to go backwards!  */
+	  gdb_assert (sym != NULL);
+	  if (strcmp_iw (SYMBOL_LINKAGE_NAME (sym), saved_arg) != 0)
+	    {
+	      xfree (values.sals);
+	      error (_("the class `%s' does not have any method instance named %s\n"),
+		     SYMBOL_PRINT_NAME (sym_class), copy);
+	    }
+	}
+      return values;
     } /* End if symbol found */
 
 
@@ -1509,8 +1537,39 @@ find_method (int funfirstline, char ***c
     }
   if (i1 > 0)
     {
-      /* There is more than one field with that name
-	 (overloaded).  Ask the user which one to use.  */
+      /* 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)
+	{
+	  int i;
+	  for (i = 0; i < i1; ++i)
+	    {
+	      char *name = saved_arg;
+	      char *canon = cp_canonicalize_string (name);
+	      if (canon != NULL)
+		name = canon;
+
+	      if (strcmp_iw (name, SYMBOL_LINKAGE_NAME (sym_arr[i])) == 0)
+		{
+		  values.sals = (struct symtab_and_line *)
+		    xmalloc (sizeof (struct symtab_and_line));
+		  values.nelts = 1;
+		  values.sals[0] = find_function_start_sal (sym_arr[i],
+							    funfirstline);
+		  if (canon)
+		    xfree (canon);
+		  return values;
+		}
+
+	      if (canon)
+		xfree (canon);
+	    }
+
+	  error (_("the class `%s' does not have any method instance named %s\n"),
+		   SYMBOL_PRINT_NAME (sym_class), copy);
+	}
+
       return decode_line_2 (sym_arr, i1, funfirstline, canonical);
     }
   else
@@ -1815,7 +1874,7 @@ symbol_found (int funfirstline, char ***
 	{
 	  struct blockvector *bv = BLOCKVECTOR (SYMBOL_SYMTAB (sym));
 	  struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-	  if (lookup_block_symbol (b, copy, NULL, VAR_DOMAIN) != NULL)
+	  if (lookup_block_symbol (b, copy, VAR_DOMAIN) != NULL)
 	    build_canonical_line_spec (values.sals, copy, canonical);
 	}
       return values;

[-- Attachment #4: dwarf2_physname-20100128.patch --]
[-- Type: text/plain, Size: 140383 bytes --]

? cl.cpexprs
? cl.dwarf2_physname
? cl.dwarf2_physname-tests
? cl.dwarf2_physname-trivial
Index: ada-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/ada-lang.c,v
retrieving revision 1.247
diff -u -p -r1.247 ada-lang.c
--- ada-lang.c	20 Jan 2010 03:34:25 -0000	1.247
+++ ada-lang.c	28 Jan 2010 23:30:18 -0000
@@ -4781,14 +4781,10 @@ ada_lookup_symbol (const char *name, con
 
 static struct symbol *
 ada_lookup_symbol_nonlocal (const char *name,
-                            const char *linkage_name,
                             const struct block *block,
                             const domain_enum domain)
 {
-  if (linkage_name == NULL)
-    linkage_name = name;
-  return ada_lookup_symbol (linkage_name, block_static_block (block), domain,
-                            NULL);
+  return ada_lookup_symbol (name, block_static_block (block), domain, NULL);
 }
 
 
Index: ax-gdb.c
===================================================================
RCS file: /cvs/src/src/gdb/ax-gdb.c,v
retrieving revision 1.61
diff -u -p -r1.61 ax-gdb.c
--- ax-gdb.c	15 Jan 2010 22:37:17 -0000	1.61
+++ ax-gdb.c	28 Jan 2010 23:30:18 -0000
@@ -1810,7 +1810,7 @@ gen_expr (struct expression *exp, union 
 
 	/* Calling lookup_block_symbol is necessary to get the LOC_REGISTER
 	   symbol instead of the LOC_ARG one (if both exist).  */
-	sym = lookup_block_symbol (b, this_name, NULL, VAR_DOMAIN);
+	sym = lookup_block_symbol (b, this_name, VAR_DOMAIN);
 	if (!sym)
 	  error (_("no `%s' found"), this_name);
 
Index: c-typeprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-typeprint.c,v
retrieving revision 1.50
diff -u -p -r1.50 c-typeprint.c
--- c-typeprint.c	1 Jan 2010 07:31:30 -0000	1.50
+++ c-typeprint.c	28 Jan 2010 23:30:18 -0000
@@ -32,6 +32,7 @@
 #include "c-lang.h"
 #include "typeprint.h"
 #include "cp-abi.h"
+#include "jv-lang.h"
 
 #include "gdb_string.h"
 #include <errno.h>
@@ -40,8 +41,6 @@ static void cp_type_print_method_args (s
 				       char *varstring, int staticp,
 				       struct ui_file *stream);
 
-static void c_type_print_args (struct type *, struct ui_file *);
-
 static void cp_type_print_derivation_info (struct ui_file *, struct type *);
 
 static void c_type_print_varspec_prefix (struct type *, struct ui_file *, int,
@@ -197,6 +196,23 @@ cp_type_print_method_args (struct type *
     fprintf_filtered (stream, "void");
 
   fprintf_filtered (stream, ")");
+
+  /* For non-static methods, read qualifiers from the type of
+     THIS.  */
+  if (!staticp)
+    {
+      struct type *domain;
+
+      gdb_assert (nargs > 0);
+      gdb_assert (TYPE_CODE (args[0].type) == TYPE_CODE_PTR);
+      domain = TYPE_TARGET_TYPE (args[0].type);
+
+      if (TYPE_CONST (domain))
+	fprintf_filtered (stream, " const");
+
+      if (TYPE_VOLATILE (domain))
+	fprintf_filtered (stream, " volatile");
+    }
 }
 
 
@@ -353,10 +369,14 @@ c_type_print_modifier (struct type *type
 
 /* Print out the arguments of TYPE, which should have TYPE_CODE_METHOD
    or TYPE_CODE_FUNC, to STREAM.  Artificial arguments, such as "this"
-   in non-static methods, are displayed.  */
+   in non-static methods, are displayed if SHOW_ARTIFICIAL is
+   non-zero. LANGUAGE is the language in which TYPE was defined.  This is
+   a necessary evil since this code is used by the C, C++, and Java
+   backends. */
 
-static void
-c_type_print_args (struct type *type, struct ui_file *stream)
+void
+c_type_print_args (struct type *type, struct ui_file *stream,
+		   int show_artificial, enum language language)
 {
   int i, len;
   struct field *args;
@@ -368,13 +388,19 @@ c_type_print_args (struct type *type, st
 
   for (i = 0; i < TYPE_NFIELDS (type); i++)
     {
+      if (TYPE_FIELD_ARTIFICIAL (type, i) && !show_artificial)
+	continue;
+
       if (printed_any)
 	{
 	  fprintf_filtered (stream, ", ");
 	  wrap_here ("    ");
 	}
 
-      c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
+      if (language == language_java)
+	java_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
+      else
+	c_print_type (TYPE_FIELD_TYPE (type, i), "", stream, -1, 0);
       printed_any = 1;
     }
 
@@ -591,7 +617,7 @@ c_type_print_varspec_suffix (struct type
       if (passed_a_ptr)
 	fprintf_filtered (stream, ")");
       if (!demangled_args)
-	c_type_print_args (type, stream);
+	c_type_print_args (type, stream, 1, language_c);
       c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show,
 				   passed_a_ptr, 0);
       break;
Index: cp-namespace.c
===================================================================
RCS file: /cvs/src/src/gdb/cp-namespace.c,v
retrieving revision 1.33
diff -u -p -r1.33 cp-namespace.c
--- cp-namespace.c	26 Jan 2010 16:47:34 -0000	1.33
+++ cp-namespace.c	28 Jan 2010 23:30:19 -0000
@@ -34,14 +34,12 @@
 #include "buildsym.h"
 
 static struct symbol *lookup_namespace_scope (const char *name,
-					      const char *linkage_name,
 					      const struct block *block,
 					      const domain_enum domain,
 					      const char *scope,
 					      int scope_len);
 
 static struct symbol *lookup_symbol_file (const char *name,
-					  const char *linkage_name,
 					  const struct block *block,
 					  const domain_enum domain,
 					  int anonymous_namespace);
@@ -223,26 +221,23 @@ cp_add_using (const char *dest,
 /* The C++-specific version of name lookup for static and global
    names.  This makes sure that names get looked for in all namespaces
    that are in scope.  NAME is the natural name of the symbol that
-   we're looking for, LINKAGE_NAME (which is optional) is its linkage
-   name, BLOCK is the block that we're searching within, DOMAIN says
-   what kind of symbols we're looking for, and if SYMTAB is non-NULL,
-   we should store the symtab where we found the symbol in it.  */
+   we're looking for, BLOCK is the block that we're searching within,
+   DOMAIN says what kind of symbols we're looking for, and if SYMTAB is
+   non-NULL, we should store the symtab where we found the symbol in it.  */
 
 struct symbol *
 cp_lookup_symbol_nonlocal (const char *name,
-			   const char *linkage_name,
 			   const struct block *block,
 			   const domain_enum domain)
 {
   struct symbol *sym;
   const char *scope = block_scope (block);
 
-  sym = lookup_namespace_scope (name, linkage_name, block, domain, scope, 0);
+  sym = lookup_namespace_scope (name, block, domain, scope, 0);
   if (sym != NULL)
     return sym;
 
-  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain,
-                                     1);
+  return cp_lookup_symbol_namespace (scope, name, block, domain, 1);
 }
 
 /* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in
@@ -251,14 +246,12 @@ cp_lookup_symbol_nonlocal (const char *n
 static struct symbol *
 cp_lookup_symbol_in_namespace (const char *namespace,
                                const char *name,
-                               const char *linkage_name,
                                const struct block *block,
                                const domain_enum domain)
 {
   if (namespace[0] == '\0')
     {
-      return lookup_symbol_file (name, linkage_name, block,
-                                 domain, 0);
+      return lookup_symbol_file (name, block, domain, 0);
     }
   else
     {
@@ -267,8 +260,8 @@ cp_lookup_symbol_in_namespace (const cha
       strcpy (concatenated_name, namespace);
       strcat (concatenated_name, "::");
       strcat (concatenated_name, name);
-      return lookup_symbol_file (concatenated_name, linkage_name,
-                                 block, domain,cp_is_anonymous (namespace));
+      return lookup_symbol_file (concatenated_name, block,
+				 domain,cp_is_anonymous (namespace));
     }
 }
 
@@ -302,7 +295,6 @@ reset_directive_searched (void *data)
 static struct symbol *
 cp_lookup_symbol_imports (const char *scope,
                           const char *name,
-                          const char *linkage_name,
                           const struct block *block,
                           const domain_enum domain,
                           const int search_parents)
@@ -314,8 +306,7 @@ cp_lookup_symbol_imports (const char *sc
   struct cleanup *searched_cleanup;
 
   /* First, try to find the symbol in the given namespace.  */
-  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
-                                       domain);
+  sym = cp_lookup_symbol_in_namespace (scope, name, block, domain);
   if (sym != NULL)
     return sym;
 
@@ -346,7 +337,6 @@ cp_lookup_symbol_imports (const char *sc
 
 	sym = cp_lookup_symbol_namespace (current->import_src,
 	                                  name,
-	                                  linkage_name,
 	                                  block,
 	                                  domain,
 	                                  0);
@@ -369,7 +359,6 @@ cp_lookup_symbol_imports (const char *sc
 struct symbol*
 cp_lookup_symbol_namespace (const char *scope,
                             const char *name,
-                            const char *linkage_name,
                             const struct block *block,
                             const domain_enum domain,
                             const int search_parents)
@@ -379,7 +368,7 @@ cp_lookup_symbol_namespace (const char *
   /* Search for name in namespaces imported to this and parent blocks.  */
   while (block != NULL)
     {
-      sym = cp_lookup_symbol_imports (scope, name, linkage_name, block, domain,
+      sym = cp_lookup_symbol_imports (scope, name, block, domain,
                                       search_parents);
 
       if (sym)
@@ -408,7 +397,6 @@ cp_lookup_symbol_namespace (const char *
 
 static struct symbol *
 lookup_namespace_scope (const char *name,
-			const char *linkage_name,
 			const struct block *block,
 			const domain_enum domain,
 			const char *scope,
@@ -430,8 +418,7 @@ lookup_namespace_scope (const char *name
 	  new_scope_len += 2;
 	}
       new_scope_len += cp_find_first_component (scope + new_scope_len);
-      sym = lookup_namespace_scope (name, linkage_name, block,
-				    domain, scope, new_scope_len);
+      sym = lookup_namespace_scope (name, block, domain, scope, new_scope_len);
       if (sym != NULL)
 	return sym;
     }
@@ -442,8 +429,7 @@ lookup_namespace_scope (const char *name
   namespace = alloca (scope_len + 1);
   strncpy (namespace, scope, scope_len);
   namespace[scope_len] = '\0';
-  return cp_lookup_symbol_in_namespace (namespace, name, linkage_name,
-                                        block, domain);
+  return cp_lookup_symbol_in_namespace (namespace, name, block, domain);
 }
 
 /* Look up NAME in BLOCK's static block and in global blocks.  If
@@ -453,14 +439,13 @@ lookup_namespace_scope (const char *name
 
 static struct symbol *
 lookup_symbol_file (const char *name,
-		    const char *linkage_name,
 		    const struct block *block,
 		    const domain_enum domain,
 		    int anonymous_namespace)
 {
   struct symbol *sym = NULL;
 
-  sym = lookup_symbol_static (name, linkage_name, block, domain);
+  sym = lookup_symbol_static (name, block, domain);
   if (sym != NULL)
     return sym;
 
@@ -473,12 +458,11 @@ lookup_symbol_file (const char *name,
       const struct block *global_block = block_global_block (block);
       
       if (global_block != NULL)
-	sym = lookup_symbol_aux_block (name, linkage_name, global_block,
-				       domain);
+	sym = lookup_symbol_aux_block (name, global_block, domain);
     }
   else
     {
-      sym = lookup_symbol_global (name, linkage_name, block, domain);
+      sym = lookup_symbol_global (name, block, domain);
     }
 
   if (sym != NULL)
@@ -528,7 +512,6 @@ cp_lookup_nested_type (struct type *pare
 	const char *parent_name = TYPE_TAG_NAME (parent_type);
 	struct symbol *sym = cp_lookup_symbol_in_namespace (parent_name,
 	                                                    nested_name,
-	                                                    NULL,
 	                                                    block,
 	                                                    VAR_DOMAIN);
 	if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF)
@@ -774,7 +757,7 @@ check_one_possible_namespace_symbol (con
 
   memcpy (name_copy, name, len);
   name_copy[len] = '\0';
-  sym = lookup_block_symbol (block, name_copy, NULL, VAR_DOMAIN);
+  sym = lookup_block_symbol (block, name_copy, VAR_DOMAIN);
 
   if (sym == NULL)
     {
@@ -815,7 +798,7 @@ lookup_possible_namespace_symbol (const 
       struct symbol *sym;
 
       sym = lookup_block_symbol (get_possible_namespace_block (objfile),
-				 name, NULL, VAR_DOMAIN);
+				 name, VAR_DOMAIN);
 
       if (sym != NULL)
 	return sym;
Index: cp-support.c
===================================================================
RCS file: /cvs/src/src/gdb/cp-support.c,v
retrieving revision 1.35
diff -u -p -r1.35 cp-support.c
--- cp-support.c	1 Jan 2010 07:31:30 -0000	1.35
+++ cp-support.c	28 Jan 2010 23:30:19 -0000
@@ -840,9 +840,9 @@ read_in_psymtabs (const char *func_name)
     if (ps->readin)
       continue;
 
-    if ((lookup_partial_symbol (ps, func_name, NULL, 1, VAR_DOMAIN)
+    if ((lookup_partial_symbol (ps, func_name, 1, VAR_DOMAIN)
 	 != NULL)
-	|| (lookup_partial_symbol (ps, func_name, NULL, 0, VAR_DOMAIN)
+	|| (lookup_partial_symbol (ps, func_name, 0, VAR_DOMAIN)
 	    != NULL))
       psymtab_to_symtab (ps);
   }
Index: cp-support.h
===================================================================
RCS file: /cvs/src/src/gdb/cp-support.h,v
retrieving revision 1.32
diff -u -p -r1.32 cp-support.h
--- cp-support.h	26 Jan 2010 16:47:34 -0000	1.32
+++ cp-support.h	28 Jan 2010 23:30:19 -0000
@@ -102,13 +102,11 @@ extern void cp_set_block_scope (const st
 extern void cp_scan_for_anonymous_namespaces (const struct symbol *symbol);
 
 extern struct symbol *cp_lookup_symbol_nonlocal (const char *name,
-						 const char *linkage_name,
 						 const struct block *block,
 						 const domain_enum domain);
 
 extern struct symbol *cp_lookup_symbol_namespace (const char *namespace,
 						  const char *name,
-						  const char *linkage_name,
 						  const struct block *block,
 						  const domain_enum domain,
 						  const int search_parents);
Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.352
diff -u -p -r1.352 dwarf2read.c
--- dwarf2read.c	26 Jan 2010 15:48:25 -0000	1.352
+++ dwarf2read.c	28 Jan 2010 23:30:21 -0000
@@ -48,6 +48,9 @@
 #include "gdbcmd.h"
 #include "block.h"
 #include "addrmap.h"
+#include "typeprint.h"
+#include "jv-lang.h"
+#include "vec.h"
 
 #include <fcntl.h>
 #include "gdb_string.h"
@@ -487,8 +490,7 @@ struct partial_die_info
     unsigned int has_byte_size : 1;
 
     /* The name of this DIE.  Normally the value of DW_AT_name, but
-       sometimes DW_TAG_MIPS_linkage_name or a string computed in some
-       other fashion.  */
+       sometimes a default name for unnamed DIEs.  */
     char *name;
 
     /* The scope to prepend to our children.  This is generally
@@ -677,6 +679,11 @@ struct field_info
     int nfnfields;
   };
 
+/* A vector used during linkage name generation.  */
+typedef struct die_info *die_info_p;
+DEF_VEC_P (die_info_p);
+static VEC(die_info_p) *die_list;
+
 /* One item on the queue of compilation units to read in full symbols
    for.  */
 struct dwarf2_queue_item
@@ -788,7 +795,7 @@ static void scan_partial_symbols (struct
 static void add_partial_symbol (struct partial_die_info *,
 				struct dwarf2_cu *);
 
-static int pdi_needs_namespace (enum dwarf_tag tag);
+static int die_needs_namespace (struct die_info *, struct dwarf2_cu *);
 
 static void add_partial_namespace (struct partial_die_info *pdi,
 				   CORE_ADDR *lowpc, CORE_ADDR *highpc,
@@ -940,6 +947,11 @@ static struct type *tag_type_to_type (st
 
 static struct type *read_type_die (struct die_info *, struct dwarf2_cu *);
 
+static char *physname_prefix (struct die_info *die, struct dwarf2_cu *);
+
+static void physname_prefix_1 (struct ui_file *, struct die_info *,
+			       struct dwarf2_cu *);
+
 static char *determine_prefix (struct die_info *die, struct dwarf2_cu *);
 
 static char *typename_concat (struct obstack *,
@@ -984,9 +996,6 @@ static void dwarf2_attach_fn_fields_to_t
 
 static void process_structure_scope (struct die_info *, struct dwarf2_cu *);
 
-static const char *determine_class_name (struct die_info *die,
-					 struct dwarf2_cu *cu);
-
 static void read_common_block (struct die_info *, struct dwarf2_cu *);
 
 static void read_namespace (struct die_info *die, struct dwarf2_cu *);
@@ -1028,7 +1037,7 @@ static gdb_byte *read_full_die (const st
 
 static void process_die (struct die_info *, struct dwarf2_cu *);
 
-static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
+static char *dwarf2_physname (struct die_info *, struct dwarf2_cu *);
 
 static char *dwarf2_canonicalize_name (char *, struct dwarf2_cu *,
 				       struct obstack *);
@@ -2441,12 +2450,9 @@ add_partial_symbol (struct partial_die_i
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  if (pdi_needs_namespace (pdi->tag))
-    {
-      actual_name = partial_die_full_name (pdi, cu);
-      if (actual_name)
-	built_actual_name = 1;
-    }
+  actual_name = partial_die_full_name (pdi, cu);
+  if (actual_name)
+    built_actual_name = 1;
 
   if (actual_name == NULL)
     actual_name = pdi->name;
@@ -2586,34 +2592,17 @@ add_partial_symbol (struct partial_die_i
       break;
     }
 
-  /* Check to see if we should scan the name for possible namespace
-     info.  Only do this if this is C++, if we don't have namespace
-     debugging info in the file, if the psym is of an appropriate type
-     (otherwise we'll have psym == NULL), and if we actually had a
-     mangled name to begin with.  */
-
-  /* FIXME drow/2004-02-22: Why don't we do this for classes, i.e. the
-     cases which do not set PSYM above?  */
-
-  if (cu->language == language_cplus
-      && cu->has_namespace_info == 0
-      && psym != NULL
-      && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
-    cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym),
-					 objfile);
-
   if (built_actual_name)
     xfree (actual_name);
 }
 
-/* Determine whether a die of type TAG living in a C++ class or
-   namespace needs to have the name of the scope prepended to the
-   name listed in the die.  */
+/* Determine whether DIE needs to have the name of the scope prepended
+   to the name listed in the die.  */
 
 static int
-pdi_needs_namespace (enum dwarf_tag tag)
+die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu)
 {
-  switch (tag)
+  switch (die->tag)
     {
     case DW_TAG_namespace:
     case DW_TAG_typedef:
@@ -2623,7 +2612,23 @@ pdi_needs_namespace (enum dwarf_tag tag)
     case DW_TAG_union_type:
     case DW_TAG_enumeration_type:
     case DW_TAG_enumerator:
+    case DW_TAG_subprogram:
+    case DW_TAG_member:
       return 1;
+
+    case DW_TAG_variable:
+      {
+	struct attribute *attr;
+	attr = dwarf2_attr (die, DW_AT_specification, cu);
+	if (attr)
+	  return 1;
+	attr = dwarf2_attr (die, DW_AT_external, cu);
+	if (attr == NULL && die->parent->tag != DW_TAG_namespace)
+	  return 0;
+	return 1;
+      }
+      break;
+
     default:
       return 0;
     }
@@ -2752,27 +2757,6 @@ guess_structure_name (struct partial_die
 
       if (real_pdi->die_parent != NULL)
 	return;
-
-      while (child_pdi != NULL)
-	{
-	  if (child_pdi->tag == DW_TAG_subprogram)
-	    {
-	      char *actual_class_name
-		= language_class_name_from_physname (cu->language_defn,
-						     child_pdi->name);
-	      if (actual_class_name != NULL)
-		{
-		  struct_pdi->name
-		    = obsavestring (actual_class_name,
-				    strlen (actual_class_name),
-				    &cu->comp_unit_obstack);
-		  xfree (actual_class_name);
-		}
-	      break;
-	    }
-
-	  child_pdi = child_pdi->die_sibling;
-	}
     }
 }
 
@@ -3340,37 +3324,52 @@ process_die (struct die_info *die, struc
 /* Return the fully qualified name of DIE, based on its DW_AT_name.
    If scope qualifiers are appropriate they will be added.  The result
    will be allocated on the objfile_obstack, or NULL if the DIE does
-   not have a name.  */
+   not have a name.
+
+   The output string will be canonicalized (if C++/Java). */
 
 static const char *
 dwarf2_full_name (struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct attribute *attr;
-  char *prefix, *name;
-  struct ui_file *buf = NULL;
+  char *name;
 
   name = dwarf2_name (die, cu);
-  if (!name)
-    return NULL;
 
   /* These are the only languages we know how to qualify names in.  */
-  if (cu->language != language_cplus
-      && cu->language != language_java)
-    return name;
+  if (name != NULL
+      && (cu->language == language_cplus || cu->language == language_java))
+    {
+      if (die_needs_namespace (die, cu))
+	{
+	  long length;
+	  char *prefix;
+	  struct ui_file *buf;
+
+	  buf = mem_fileopen ();
+	  prefix = determine_prefix (die, cu);
+	  if (*prefix != '\0')
+	    {
+	      char *prefixed_name = typename_concat (NULL, prefix, name, cu);
+	      fputs_unfiltered (prefixed_name, buf);
+	      xfree (prefixed_name);
+	    }
+	  else
+	    fputs_unfiltered (name, buf);
 
-  /* If no prefix is necessary for this type of DIE, return the
-     unqualified name.  The other three tags listed could be handled
-     in pdi_needs_namespace, but that requires broader changes.  */
-  if (!pdi_needs_namespace (die->tag)
-      && die->tag != DW_TAG_subprogram
-      && die->tag != DW_TAG_variable
-      && die->tag != DW_TAG_member)
-    return name;
+	  name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack,
+				       &length);
+	  ui_file_delete (buf);
 
-  prefix = determine_prefix (die, cu);
-  if (*prefix != '\0')
-    name = typename_concat (&cu->objfile->objfile_obstack, prefix,
-			    name, cu);
+	  if (cu->language == language_cplus)
+	    {
+	      char *cname
+		= dwarf2_canonicalize_name (name, cu,
+					    &cu->objfile->objfile_obstack);
+	      if (cname != NULL)
+		name = cname;
+	    }
+	}
+    }
 
   return name;
 }
@@ -3843,7 +3842,7 @@ read_func_scope (struct die_info *die, s
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  name = dwarf2_linkage_name (die, cu);
+  name = dwarf2_name (die, cu);
 
   /* Ignore functions with missing or empty names and functions with
      missing or invalid low and high pc attributes.  */
@@ -4517,7 +4516,7 @@ dwarf2_add_field (struct field_info *fip
 	return;
 
       /* Get physical name.  */
-      physname = dwarf2_linkage_name (die, cu);
+      physname = dwarf2_physname (die, cu);
 
       /* The name is already allocated along with this objfile, so we don't
 	 need to duplicate it for the type.  */
@@ -4679,7 +4678,7 @@ dwarf2_add_member_fn (struct field_info 
     return;
 
   /* Get the mangled name.  */
-  physname = dwarf2_linkage_name (die, cu);
+  physname = dwarf2_physname (die, cu);
 
   /* Look up member function name in fieldlist.  */
   for (i = 0; i < fip->nfnfields; i++)
@@ -4986,14 +4985,18 @@ read_structure_type (struct die_info *di
       if (cu->language == language_cplus
 	  || cu->language == language_java)
 	{
-	  const char *new_prefix = determine_class_name (die, cu);
-	  TYPE_TAG_NAME (type) = (char *) new_prefix;
+	  TYPE_TAG_NAME (type) = (char *) dwarf2_full_name (die, cu);
+	  if (die->tag == DW_TAG_structure_type
+	      || die->tag == DW_TAG_class_type)
+	    TYPE_NAME (type) = TYPE_TAG_NAME (type);
 	}
       else
 	{
 	  /* The name is already allocated along with this objfile, so
 	     we don't need to duplicate it for the type.  */
-	  TYPE_TAG_NAME (type) = name;
+	  TYPE_TAG_NAME (type) = (char *) name;
+	  if (die->tag == DW_TAG_class_type)
+	    TYPE_NAME (type) = TYPE_TAG_NAME (type);
 	}
     }
 
@@ -5236,51 +5239,6 @@ read_enumeration_type (struct die_info *
   return set_die_type (die, type, cu);
 }
 
-/* Determine the name of the type represented by DIE, which should be
-   a named C++ or Java compound type.  Return the name in question,
-   allocated on the objfile obstack.  */
-
-static const char *
-determine_class_name (struct die_info *die, struct dwarf2_cu *cu)
-{
-  const char *new_prefix = NULL;
-
-  /* If we don't have namespace debug info, guess the name by trying
-     to demangle the names of members, just like we did in
-     guess_structure_name.  */
-  if (!processing_has_namespace_info)
-    {
-      struct die_info *child;
-
-      for (child = die->child;
-	   child != NULL && child->tag != 0;
-	   child = sibling_die (child))
-	{
-	  if (child->tag == DW_TAG_subprogram)
-	    {
-	      char *phys_prefix
-		= language_class_name_from_physname (cu->language_defn,
-						     dwarf2_linkage_name
-						     (child, cu));
-
-	      if (phys_prefix != NULL)
-		{
-		  new_prefix
-		    = obsavestring (phys_prefix, strlen (phys_prefix),
-				    &cu->objfile->objfile_obstack);
-		  xfree (phys_prefix);
-		  break;
-		}
-	    }
-	}
-    }
-
-  if (new_prefix == NULL)
-    new_prefix = dwarf2_full_name (die, cu);
-
-  return new_prefix;
-}
-
 /* Given a pointer to a die which begins an enumeration, process all
    the dies that define the members of the enumeration, and create the
    symbol for the enumeration type.
@@ -6764,7 +6722,8 @@ read_partial_die (struct partial_die_inf
 	    }
 	  break;
 	case DW_AT_MIPS_linkage_name:
-	  part_die->name = DW_STRING (&attr);
+	  if (cu->language == language_ada)
+	    part_die->name = DW_STRING (&attr);
 	  break;
 	case DW_AT_low_pc:
 	  has_low_pc_attr = 1;
@@ -8329,13 +8288,11 @@ new_symbol (struct die_info *die, struct
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  if (die->tag != DW_TAG_namespace)
-    name = dwarf2_linkage_name (die, cu);
-  else
-    name = TYPE_NAME (type);
-
+  name = dwarf2_name (die, cu);
   if (name)
     {
+      const char *linkagename;
+
       sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
 					     sizeof (struct symbol));
       OBJSTAT (objfile, n_syms++);
@@ -8343,7 +8300,8 @@ new_symbol (struct die_info *die, struct
 
       /* Cache this symbol's name and the name's demangled form (if any).  */
       SYMBOL_LANGUAGE (sym) = cu->language;
-      SYMBOL_SET_NAMES (sym, name, strlen (name), 0, objfile);
+      linkagename = dwarf2_physname (die, cu);
+      SYMBOL_SET_NAMES (sym, linkagename, strlen (linkagename), 0, objfile);
 
       /* Default assumptions.
          Use the passed type or decode it from the die.  */
@@ -8617,8 +8575,7 @@ new_symbol (struct die_info *die, struct
       /* For the benefit of old versions of GCC, check for anonymous
 	 namespaces based on the demangled name.  */
       if (!processing_has_namespace_info
-	  && cu->language == language_cplus
-	  && dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu) != NULL)
+	  && cu->language == language_cplus)
 	cp_scan_for_anonymous_namespaces (sym);
     }
   return (sym);
@@ -9021,6 +8978,96 @@ determine_prefix (struct die_info *die, 
       }
 }
 
+/* Determines the prefix for a symbol's physname.  Unlike determine_prefix,
+   this method does not simply look at the DIE's immediate parent.
+   It will compute the symbol's physname by scanning through all parent
+   DIEs until it gets to the compilation unit's DIE.  */
+
+static char *
+physname_prefix (struct die_info *die, struct dwarf2_cu *cu)
+{
+  long length;
+  struct ui_file *buf;
+  struct die_info *d, *spec_die;
+  struct dwarf2_cu *spec_cu;
+  char *name;
+
+  /* Construct a stack containing all of the DIE's parents.  Caution
+     must be observed for dealing with DW_AT_specification. */
+  spec_cu = cu;
+  spec_die = die_specification (die, &spec_cu);
+  if (spec_die != NULL)
+    d = spec_die->parent;
+  else
+    d = die->parent;
+  while (d != NULL && d->tag != DW_TAG_compile_unit)
+    {
+      struct attribute *attr;
+
+      spec_die = die_specification (d, &spec_cu);
+      if (spec_die != NULL)
+	d = spec_die;
+
+      VEC_quick_push (die_info_p, die_list, d);
+      d = d->parent;
+    }
+
+  /* Now pop all the elements, printing their names as we go.  */
+  buf = mem_fileopen ();
+  while (!VEC_empty (die_info_p, die_list))
+    {
+      d = VEC_pop (die_info_p, die_list);
+      physname_prefix_1 (buf, d, cu);
+
+      if (!VEC_empty (die_info_p, die_list))
+	{
+	  if (cu->language == language_cplus)
+	    fputs_unfiltered ("::", buf);
+	  else
+	    fputs_unfiltered (".", buf);
+	}
+    }
+
+  name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack, &length);
+  ui_file_delete (buf);
+  return name;
+}
+
+static void
+physname_prefix_1 (struct ui_file *buf, struct die_info *die,
+		   struct dwarf2_cu *cu)
+{
+  const char *name = NULL;
+  gdb_assert (buf != NULL);
+
+  if (die != NULL)
+    {
+      switch (die->tag)
+	{
+	case DW_TAG_namespace:
+	  name = dwarf2_name (die, cu);
+	  if (name == NULL)
+	    name = "(anonymous namespace)";
+	  break;
+
+	case DW_TAG_class_type:
+	case DW_TAG_structure_type:
+	case DW_TAG_union_type:
+	case DW_TAG_enumeration_type:
+	case DW_TAG_interface_type:
+	case DW_TAG_subprogram:
+	  name = dwarf2_name (die, cu);
+	  break;
+
+	default:
+	  break;
+	}
+    }
+
+  if (name != NULL)
+    fputs_unfiltered (name, buf);
+}
+
 /* Return a newly-allocated string formed by concatenating PREFIX and
    SUFFIX with appropriate separator.  If PREFIX or SUFFIX is NULL or empty, then
    simply copy the SUFFIX or PREFIX, respectively.  If OBS is non-null,
@@ -9070,17 +9117,78 @@ sibling_die (struct die_info *die)
   return die->sibling;
 }
 
-/* Get linkage name of a die, return NULL if not found.  */
+/* Construct a physname for the given DIE in CU. */
 
 static char *
-dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
+dwarf2_physname (struct die_info *die, struct dwarf2_cu *cu)
 {
   struct attribute *attr;
+  char *name;
+
+  name = dwarf2_name (die, cu);
+
+  /* These are the only languages we know how to qualify names in.  */
+  if (cu->language != language_cplus
+      && cu->language != language_java)
+    return name;
+
+  if (die_needs_namespace (die, cu))
+    {
+      long length;
+      char *prefix;
+      struct ui_file *buf;
+
+      prefix = physname_prefix (die, cu);
+      buf = mem_fileopen ();
+      if (*prefix != '\0')
+	{
+	  char *prefixed_name = typename_concat (NULL, prefix, name, cu);
+	  fputs_unfiltered (prefixed_name, buf);
+	  xfree (prefixed_name);
+	}
+      else
+	fputs_unfiltered (name ? name : "", buf);
+
+      /* For Java and C++ methods, append formal parameter type
+	 information. */
+      if ((cu->language == language_cplus || cu->language == language_java)
+	  && die->tag == DW_TAG_subprogram)
+	{
+	  struct type *type = read_type_die (die, cu);
 
-  attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
-  if (attr && DW_STRING (attr))
-    return DW_STRING (attr);
-  return dwarf2_name (die, cu);
+	  c_type_print_args (type, buf, 0, cu->language);
+
+	  if (cu->language == language_java)
+	    {
+	      /* For java, we must append the return type to method names. */
+	      if (die->tag == DW_TAG_subprogram)
+		java_print_type (TYPE_TARGET_TYPE (type), "", buf, 0, 0);
+	    }
+	  else if (cu->language == language_cplus)
+	    {
+	      /* c_type_print_args adds argument types, but it does
+		 not add any necessary "const". */
+	      if (TYPE_NFIELDS (type) > 0 && TYPE_FIELD_ARTIFICIAL (type, 0)
+		  && TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0))))
+		fputs_unfiltered (" const", buf);
+	    }
+	}
+
+      name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack,
+				   &length);
+      ui_file_delete (buf);
+
+      if (cu->language == language_cplus)
+	{
+	  char *cname
+	    = dwarf2_canonicalize_name (name, cu,
+					&cu->objfile->objfile_obstack);
+	  if (cname != NULL)
+	    name = cname;
+	}
+    }
+
+  return name;
 }
 
 /* Get name of a die, return NULL if not found.  */
@@ -11977,6 +12085,7 @@ void _initialize_dwarf2_read (void);
 void
 _initialize_dwarf2_read (void)
 {
+  die_list = VEC_alloc (die_info_p, 32);
   dwarf2_objfile_data_key
     = register_objfile_data_with_cleanup (NULL, dwarf2_per_objfile_free);
 
Index: gnu-v3-abi.c
===================================================================
RCS file: /cvs/src/src/gdb/gnu-v3-abi.c,v
retrieving revision 1.58
diff -u -p -r1.58 gnu-v3-abi.c
--- gnu-v3-abi.c	1 Jan 2010 07:31:32 -0000	1.58
+++ gnu-v3-abi.c	28 Jan 2010 23:30:21 -0000
@@ -26,6 +26,7 @@
 #include "demangle.h"
 #include "objfiles.h"
 #include "valprint.h"
+#include "c-lang.h"
 
 #include "gdb_assert.h"
 #include "gdb_string.h"
@@ -456,10 +457,8 @@ gnuv3_find_method_in (struct type *domai
 		      LONGEST adjustment)
 {
   int i;
-  const char *physname;
 
   /* Search this class first.  */
-  physname = NULL;
   if (adjustment == 0)
     {
       int len;
@@ -587,15 +586,24 @@ gnuv3_print_method_ptr (const gdb_byte *
 	{
 	  char *demangled_name = cplus_demangle (physname,
 						 DMGL_ANSI | DMGL_PARAMS);
-	  if (demangled_name != NULL)
+	  fprintf_filtered (stream, "&virtual ");
+	  if (demangled_name == NULL)
+	    fputs_filtered (physname, stream);
+	  else
 	    {
-	      fprintf_filtered (stream, "&virtual ");
 	      fputs_filtered (demangled_name, stream);
 	      xfree (demangled_name);
-	      return;
 	    }
+	  return;
 	}
     }
+  else if (ptr_value != 0)
+    {
+      /* Found a non-virtual function: print out the type.  */
+      fputs_filtered ("(", stream);
+      c_print_type (type, "", stream, -1, 0);
+      fputs_filtered (") ", stream);
+    }
 
   /* We didn't find it; print the raw data.  */
   if (vbit)
Index: language.h
===================================================================
RCS file: /cvs/src/src/gdb/language.h,v
retrieving revision 1.62
diff -u -p -r1.62 language.h
--- language.h	14 Jan 2010 08:03:36 -0000	1.62
+++ language.h	28 Jan 2010 23:30:21 -0000
@@ -237,7 +237,6 @@ struct language_defn
        variables.  */
 
     struct symbol *(*la_lookup_symbol_nonlocal) (const char *,
-						 const char *,
 						 const struct block *,
 						 const domain_enum);
 
Index: linespec.c
===================================================================
RCS file: /cvs/src/src/gdb/linespec.c,v
retrieving revision 1.95
diff -u -p -r1.95 linespec.c
--- linespec.c	12 Jan 2010 05:48:56 -0000	1.95
+++ linespec.c	28 Jan 2010 23:30:22 -0000
@@ -40,6 +40,7 @@
 #include "interps.h"
 #include "mi/mi-cmds.h"
 #include "target.h"
+#include "arch-utils.h"
 
 /* We share this one with symtab.c, but it is not exported widely. */
 
@@ -50,8 +51,6 @@ extern char *operator_chars (char *, cha
 static void initialize_defaults (struct symtab **default_symtab,
 				 int *default_line);
 
-static void set_flags (char *arg, int *is_quoted, char **paren_pointer);
-
 static struct symtabs_and_lines decode_indirect (char **argptr);
 
 static char *locate_first_half (char **argptr, int *is_quote_enclosed);
@@ -628,6 +627,37 @@ See set/show multiple-symbol."));
   discard_cleanups (old_chain);
   return return_values;
 }
+
+/* A helper function for decode_line_1 and friends which skips P
+   past any method overload information at the beginning of P, e.g.,
+   "(const struct foo *)".
+
+   This function assumes that P has already been validated to contain
+   overload information, and it will assert if *P != '('.  */
+static char *
+find_method_overload_end (char *p)
+{
+  int depth = 0;
+
+  gdb_assert (*p == '(');
+
+  while (*p)
+    {
+      if (*p == '(')
+	++depth;
+      else if (*p == ')')
+	{
+	  if (--depth == 0)
+	    {
+	      ++p;
+	      break;
+	    }
+	}
+      ++p;
+    }
+
+  return p;
+}
 \f
 /* The parser of linespec itself. */
 
@@ -688,9 +718,6 @@ decode_line_1 (char **argptr, int funfir
   struct symtab *file_symtab = NULL;
 
   char *copy;
-  /* This is NULL if there are no parens in *ARGPTR, or a pointer to
-     the closing parenthesis if there are parens.  */
-  char *paren_pointer;
   /* This says whether or not something in *ARGPTR is quoted with
      completer_quotes (i.e. with single quotes).  */
   int is_quoted;
@@ -711,12 +738,9 @@ decode_line_1 (char **argptr, int funfir
   if (**argptr == '*')
     return decode_indirect (argptr);
 
-  /* Set various flags.  'paren_pointer' is important for overload
-     checking, where we allow things like:
-        (gdb) break c::f(int)
-  */
-
-  set_flags (*argptr, &is_quoted, &paren_pointer);
+  is_quoted = (*argptr
+	       && strchr (get_gdb_completer_quote_characters (),
+			  **argptr) != NULL);
 
   /* Check to see if it's a multipart linespec (with colons or
      periods).  */
@@ -732,10 +756,7 @@ decode_line_1 (char **argptr, int funfir
   /* Check if this is an Objective-C method (anything that starts with
      a '+' or '-' and a '[').  */
   if (is_objc_method_format (p))
-    {
-      is_objc_method = 1;
-      paren_pointer  = NULL; /* Just a category name.  Ignore it.  */
-    }
+    is_objc_method = 1;
 
   /* Check if the symbol could be an Objective-C selector.  */
 
@@ -749,7 +770,7 @@ decode_line_1 (char **argptr, int funfir
 
   /* Does it look like there actually were two parts?  */
 
-  if ((p[0] == ':' || p[0] == '.') && paren_pointer == NULL)
+  if (p[0] == ':' || p[0] == '.')
     {
       if (is_quoted)
 	*argptr = *argptr + 1;
@@ -762,48 +783,31 @@ decode_line_1 (char **argptr, int funfir
 	 can return now. */
 	
       if (p[0] == '.' || p[1] == ':')
-	return decode_compound (argptr, funfirstline, canonical,
-				saved_arg, p, not_found_ptr);
+	{
+	  struct symtabs_and_lines values;
+
+	  if (is_quote_enclosed)
+	    ++saved_arg;
+	  values = decode_compound (argptr, funfirstline, canonical,
+				    saved_arg, p, not_found_ptr);
+	  if (is_quoted && **argptr == '\'')
+	    *argptr = *argptr + 1;
+	  return values;
+	}
 
       /* No, the first part is a filename; set file_symtab to be that file's
 	 symtab.  Also, move argptr past the filename.  */
 
       file_symtab = symtab_from_filename (argptr, p, is_quote_enclosed, 
 		      			  not_found_ptr);
-    }
-#if 0
-  /* No one really seems to know why this was added. It certainly
-     breaks the command line, though, whenever the passed
-     name is of the form ClassName::Method. This bit of code
-     singles out the class name, and if funfirstline is set (for
-     example, you are setting a breakpoint at this function),
-     you get an error. This did not occur with earlier
-     verions, so I am ifdef'ing this out. 3/29/99 */
-  else
-    {
-      /* Check if what we have till now is a symbol name */
-
-      /* We may be looking at a template instantiation such
-         as "foo<int>".  Check here whether we know about it,
-         instead of falling through to the code below which
-         handles ordinary function names, because that code
-         doesn't like seeing '<' and '>' in a name -- the
-         skip_quoted call doesn't go past them.  So see if we
-         can figure it out right now. */
-
-      copy = (char *) alloca (p - *argptr + 1);
-      memcpy (copy, *argptr, p - *argptr);
-      copy[p - *argptr] = '\000';
-      sym = lookup_symbol (copy, 0, VAR_DOMAIN, 0);
-      if (sym)
+      if (file_symtab != NULL)
 	{
-	  *argptr = (*p == '\'') ? p + 1 : p;
-	  return symbol_found (funfirstline, canonical, copy, sym, NULL);
+	  /* Double-check if the remainder of the argument is quoted.
+	     The rbreak command uses syntax like this.  */
+	  if (**argptr == '\'')
+	    is_quoted = 1;
 	}
-      /* Otherwise fall out from here and go to file/line spec
-         processing, etc. */
     }
-#endif
 
   /* file_symtab is specified file's symtab, or 0 if no file specified.
      arg no longer contains the file name.  */
@@ -838,10 +842,6 @@ decode_line_1 (char **argptr, int funfir
       /* allow word separators in method names for Obj-C */
       p = skip_quoted_chars (*argptr, NULL, "");
     }
-  else if (paren_pointer != NULL)
-    {
-      p = paren_pointer + 1;
-    }
   else
     {
       p = skip_quoted (*argptr);
@@ -851,6 +851,14 @@ decode_line_1 (char **argptr, int funfir
   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;
+
   copy = (char *) alloca (p - *argptr + 1);
   memcpy (copy, *argptr, p - *argptr);
   copy[p - *argptr] = '\0';
@@ -926,44 +934,6 @@ initialize_defaults (struct symtab **def
     }
 }
 
-static void
-set_flags (char *arg, int *is_quoted, char **paren_pointer)
-{
-  char *ii;
-  int has_if = 0;
-
-  /* 'has_if' is for the syntax:
-        (gdb) break foo if (a==b)
-  */
-  if ((ii = strstr (arg, " if ")) != NULL ||
-      (ii = strstr (arg, "\tif ")) != NULL ||
-      (ii = strstr (arg, " if\t")) != NULL ||
-      (ii = strstr (arg, "\tif\t")) != NULL ||
-      (ii = strstr (arg, " if(")) != NULL ||
-      (ii = strstr (arg, "\tif( ")) != NULL)
-    has_if = 1;
-  /* Temporarily zap out "if (condition)" to not confuse the
-     parenthesis-checking code below.  This is undone below. Do not
-     change ii!!  */
-  if (has_if)
-    {
-      *ii = '\0';
-    }
-
-  *is_quoted = (*arg
-		&& strchr (get_gdb_completer_quote_characters (),
-			   *arg) != NULL);
-
-  *paren_pointer = strchr (arg, '(');
-  if (*paren_pointer != NULL)
-    *paren_pointer = strrchr (*paren_pointer, ')');
-
-  /* Now that we're safely past the paren_pointer check, put back " if
-     (condition)" so outer layers can see it.  */
-  if (has_if)
-    *ii = ' ';
-}
-
 \f
 
 /* Decode arg of the form *PC.  */
@@ -1063,8 +1033,9 @@ locate_first_half (char **argptr, int *i
       if (p[0] == '.' && strchr (p, ':') == NULL)
 	{
 	  /* Java qualified method.  Find the *last* '.', since the
-	     others are package qualifiers.  */
-	  for (p1 = p; *p1; p1++)
+	     others are package qualifiers.  Stop at any open parenthesis
+	     which might provide overload information.  */
+	  for (p1 = p; *p1 && *p1 != '('; p1++)
 	    {
 	      if (*p1 == '.')
 		p = p1;
@@ -1216,6 +1187,7 @@ decode_compound (char **argptr, int funf
   struct symbol *sym_class;
   struct symbol **sym_arr;
   struct type *t;
+  char *saved_java_argptr = NULL;
 
   /* First check for "global" namespace specification, of the form
      "::foo".  If found, skip over the colons and jump to normal
@@ -1264,7 +1236,8 @@ 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] != '\''))
+      while (*p && (p[0] != ' ') && (p[0] != '\t') && (p[0] != '\'')
+	     && (*p != '('))
 	{
 	  if (current_language->la_language == language_cplus)
 	    p += cp_validate_operator (p);
@@ -1342,8 +1315,10 @@ decode_compound (char **argptr, int funf
       else
 	{
 	  /* At this point argptr->"fun".  */
+	  char *a;
 	  p = *argptr;
-	  while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':')
+	  while (*p && *p != ' ' && *p != '\t' && *p != ',' && *p != ':'
+		 && *p != '(')
 	    p++;
 	  /* At this point p->"".  String ended.  */
 	  /* Nope, C++ operators could have spaces in them
@@ -1355,6 +1330,42 @@ decode_compound (char **argptr, int funf
 	      /* The above loop has already swallowed "operator".  */
 	      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;
+
+	  /* Java may append typenames,  so assume that if there is
+	     anything else left in *argptr, it must be a typename.  */
+	  if (*p && current_language->la_language == language_java)
+	    {
+	      struct type *type;
+	      p2 = p;
+	      while (*p2)
+		++p2;
+	      copy = (char *) alloca (p2 - p + 1);
+	      memcpy (copy, p, p2 - p);
+	      copy[p2 - p] = '\0';
+	      type = lookup_typename (current_language, get_current_arch (),
+				      copy, NULL, 1);
+	      if (type != NULL)
+		{
+		  /* Save the location of this just in case this
+		     method/type combination isn't actually defined.
+		     It will be checked later.  */
+		  saved_java_argptr = p;
+		  p = p2;
+		}
+	    }
 	}
 
       /* Allocate our own copy of the substring between argptr and
@@ -1383,9 +1394,26 @@ decode_compound (char **argptr, int funf
 	 here, we return. If not, and we are at the and of the string,
 	 we'll lookup the whole string in the symbol tables.  */
 
-      return find_method (funfirstline, canonical, saved_arg,
-			  copy, t, sym_class, not_found_ptr);
-
+      values = find_method (funfirstline, canonical, saved_arg,
+			    copy, t, sym_class, not_found_ptr);
+      if (saved_java_argptr != NULL && values.nelts == 1)
+	{
+	  /* The user specified a specific return type for a java method.
+	     Double-check that it really is the one the user specified.
+	     [This is a necessary evil because strcmp_iw_ordered stops
+	     comparisons too prematurely.]  */
+	  sym = find_pc_sect_function (values.sals[0].pc,
+				       values.sals[0].section);
+	  /* We just found a SAL, we had better be able to go backwards!  */
+	  gdb_assert (sym != NULL);
+	  if (strcmp_iw (SYMBOL_LINKAGE_NAME (sym), saved_arg) != 0)
+	    {
+	      xfree (values.sals);
+	      error (_("the class `%s' does not have any method instance named %s\n"),
+		     SYMBOL_PRINT_NAME (sym_class), copy);
+	    }
+	}
+      return values;
     } /* End if symbol found */
 
 
@@ -1509,8 +1537,39 @@ find_method (int funfirstline, char ***c
     }
   if (i1 > 0)
     {
-      /* There is more than one field with that name
-	 (overloaded).  Ask the user which one to use.  */
+      /* 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)
+	{
+	  int i;
+	  for (i = 0; i < i1; ++i)
+	    {
+	      char *name = saved_arg;
+	      char *canon = cp_canonicalize_string (name);
+	      if (canon != NULL)
+		name = canon;
+
+	      if (strcmp_iw (name, SYMBOL_LINKAGE_NAME (sym_arr[i])) == 0)
+		{
+		  values.sals = (struct symtab_and_line *)
+		    xmalloc (sizeof (struct symtab_and_line));
+		  values.nelts = 1;
+		  values.sals[0] = find_function_start_sal (sym_arr[i],
+							    funfirstline);
+		  if (canon)
+		    xfree (canon);
+		  return values;
+		}
+
+	      if (canon)
+		xfree (canon);
+	    }
+
+	  error (_("the class `%s' does not have any method instance named %s\n"),
+		   SYMBOL_PRINT_NAME (sym_class), copy);
+	}
+
       return decode_line_2 (sym_arr, i1, funfirstline, canonical);
     }
   else
@@ -1815,7 +1874,7 @@ symbol_found (int funfirstline, char ***
 	{
 	  struct blockvector *bv = BLOCKVECTOR (SYMBOL_SYMTAB (sym));
 	  struct block *b = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-	  if (lookup_block_symbol (b, copy, NULL, VAR_DOMAIN) != NULL)
+	  if (lookup_block_symbol (b, copy, VAR_DOMAIN) != NULL)
 	    build_canonical_line_spec (values.sals, copy, canonical);
 	}
       return values;
Index: scm-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/scm-valprint.c,v
retrieving revision 1.29
diff -u -p -r1.29 scm-valprint.c
--- scm-valprint.c	1 Jan 2010 07:31:41 -0000	1.29
+++ scm-valprint.c	28 Jan 2010 23:30:22 -0000
@@ -62,9 +62,9 @@ scm_inferior_print (struct type *type, L
     {
       /* XXX: Should we cache these symbols?  */
       gdb_output_sym =
-	lookup_symbol_global ("gdb_output", NULL, NULL, VAR_DOMAIN);
+	lookup_symbol_global ("gdb_output", NULL, VAR_DOMAIN);
       gdb_output_len_sym =
-	lookup_symbol_global ("gdb_output_length", NULL, NULL, VAR_DOMAIN);
+	lookup_symbol_global ("gdb_output_length", NULL, VAR_DOMAIN);
 
       if ((gdb_output_sym == NULL) || (gdb_output_len_sym == NULL))
 	ret = -1;
Index: solib-darwin.c
===================================================================
RCS file: /cvs/src/src/gdb/solib-darwin.c,v
retrieving revision 1.11
diff -u -p -r1.11 solib-darwin.c
--- solib-darwin.c	8 Jan 2010 22:52:03 -0000	1.11
+++ solib-darwin.c	28 Jan 2010 23:30:22 -0000
@@ -408,7 +408,6 @@ darwin_relocate_section_addresses (struc
 static struct symbol *
 darwin_lookup_lib_symbol (const struct objfile *objfile,
 			  const char *name,
-			  const char *linkage_name,
 			  const domain_enum domain)
 {
   return NULL;
Index: solib-svr4.c
===================================================================
RCS file: /cvs/src/src/gdb/solib-svr4.c,v
retrieving revision 1.116
diff -u -p -r1.116 solib-svr4.c
--- solib-svr4.c	27 Jan 2010 00:32:09 -0000	1.116
+++ solib-svr4.c	28 Jan 2010 23:30:22 -0000
@@ -1961,7 +1961,6 @@ struct target_so_ops svr4_so_ops;
 static struct symbol *
 elf_lookup_lib_symbol (const struct objfile *objfile,
 		       const char *name,
-		       const char *linkage_name,
 		       const domain_enum domain)
 {
   bfd *abfd;
@@ -1979,8 +1978,7 @@ elf_lookup_lib_symbol (const struct objf
   if (abfd == NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL) != 1)
     return NULL;
 
-  return lookup_global_symbol_from_objfile
-		(objfile, name, linkage_name, domain);
+  return lookup_global_symbol_from_objfile (objfile, name, domain);
 }
 
 extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */
Index: solib.c
===================================================================
RCS file: /cvs/src/src/gdb/solib.c,v
retrieving revision 1.133
diff -u -p -r1.133 solib.c
--- solib.c	20 Jan 2010 14:23:07 -0000	1.133
+++ solib.c	28 Jan 2010 23:30:23 -0000
@@ -1154,13 +1154,12 @@ show_auto_solib_add (struct ui_file *fil
 struct symbol *
 solib_global_lookup (const struct objfile *objfile,
 		     const char *name,
-		     const char *linkage_name,
 		     const domain_enum domain)
 {
   struct target_so_ops *ops = solib_ops (target_gdbarch);
 
   if (ops->lookup_lib_global_symbol != NULL)
-    return ops->lookup_lib_global_symbol (objfile, name, linkage_name, domain);
+    return ops->lookup_lib_global_symbol (objfile, name, domain);
   return NULL;
 }
 
Index: solist.h
===================================================================
RCS file: /cvs/src/src/gdb/solist.h,v
retrieving revision 1.29
diff -u -p -r1.29 solist.h
--- solist.h	8 Jan 2010 22:52:04 -0000	1.29
+++ solist.h	28 Jan 2010 23:30:23 -0000
@@ -117,7 +117,6 @@ struct target_so_ops
     /* Hook for looking up global symbols in a library-specific way.  */
     struct symbol * (*lookup_lib_global_symbol) (const struct objfile *objfile,
 						 const char *name,
-						 const char *linkage_name,
 						 const domain_enum domain);
 
     /* Given two so_list objects, one from the GDB thread list
@@ -157,7 +156,6 @@ extern struct target_so_ops *current_tar
 /* Handler for library-specific global symbol lookup in solib.c.  */
 struct symbol *solib_global_lookup (const struct objfile *objfile,
 				    const char *name,
-				    const char *linkage_name,
 				    const domain_enum domain);
 
 #endif
Index: symmisc.c
===================================================================
RCS file: /cvs/src/src/gdb/symmisc.c,v
retrieving revision 1.67
diff -u -p -r1.67 symmisc.c
--- symmisc.c	1 Jan 2010 07:31:42 -0000	1.67
+++ symmisc.c	28 Jan 2010 23:30:23 -0000
@@ -1143,7 +1143,7 @@ maintenance_check_symtabs (char *ignore,
     while (length--)
       {
 	sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym),
-				   NULL, SYMBOL_DOMAIN (*psym));
+				   SYMBOL_DOMAIN (*psym));
 	if (!sym)
 	  {
 	    printf_filtered ("Static symbol `");
@@ -1160,7 +1160,7 @@ maintenance_check_symtabs (char *ignore,
     while (length--)
       {
 	sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym),
-				   NULL, SYMBOL_DOMAIN (*psym));
+				   SYMBOL_DOMAIN (*psym));
 	if (!sym)
 	  {
 	    printf_filtered ("Global symbol `");
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.224
diff -u -p -r1.224 symtab.c
--- symtab.c	26 Jan 2010 15:48:25 -0000	1.224
+++ symtab.c	28 Jan 2010 23:30:24 -0000
@@ -85,7 +85,6 @@ static int find_line_common (struct line
 char *operator_chars (char *p, char **end);
 
 static struct symbol *lookup_symbol_aux (const char *name,
-					 const char *linkage_name,
 					 const struct block *block,
 					 const domain_enum domain,
 					 enum language language,
@@ -93,20 +92,17 @@ static struct symbol *lookup_symbol_aux 
 
 static
 struct symbol *lookup_symbol_aux_local (const char *name,
-					const char *linkage_name,
 					const struct block *block,
 					const domain_enum domain);
 
 static
 struct symbol *lookup_symbol_aux_symtabs (int block_index,
 					  const char *name,
-					  const char *linkage_name,
 					  const domain_enum domain);
 
 static
 struct symbol *lookup_symbol_aux_psymtabs (int block_index,
 					   const char *name,
-					   const char *linkage_name,
 					   const domain_enum domain);
 
 static int file_matches (char *, char **, int);
@@ -498,7 +494,7 @@ symbol_find_demangled_name (struct gener
       || gsymbol->language == language_auto)
     {
       demangled =
-        cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI);
+        cplus_demangle (mangled, DMGL_PARAMS | DMGL_ANSI | DMGL_VERBOSE);
       if (demangled != NULL)
 	{
 	  gsymbol->language = language_cplus;
@@ -1257,7 +1253,6 @@ lookup_symbol_in_language (const char *n
 {
   char *demangled_name = NULL;
   const char *modified_name = NULL;
-  const char *mangled_name = NULL;
   struct symbol *returnval;
   struct cleanup *cleanup = make_cleanup (null_cleanup, 0);
 
@@ -1270,7 +1265,6 @@ lookup_symbol_in_language (const char *n
       demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
       if (demangled_name)
 	{
-	  mangled_name = name;
 	  modified_name = demangled_name;
 	  make_cleanup (xfree, demangled_name);
 	}
@@ -1292,7 +1286,6 @@ lookup_symbol_in_language (const char *n
 		      		       DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
       if (demangled_name)
 	{
-	  mangled_name = name;
 	  modified_name = demangled_name;
 	  make_cleanup (xfree, demangled_name);
 	}
@@ -1311,8 +1304,8 @@ lookup_symbol_in_language (const char *n
       modified_name = copy;
     }
 
-  returnval = lookup_symbol_aux (modified_name, mangled_name, block,
-				 domain, lang, is_a_field_of_this);
+  returnval = lookup_symbol_aux (modified_name, block, domain, lang,
+				 is_a_field_of_this);
   do_cleanups (cleanup);
 
   return returnval;
@@ -1336,9 +1329,9 @@ lookup_symbol (const char *name, const s
    well.  */
 
 static struct symbol *
-lookup_symbol_aux (const char *name, const char *linkage_name,
-		   const struct block *block, const domain_enum domain,
-		   enum language language, int *is_a_field_of_this)
+lookup_symbol_aux (const char *name, const struct block *block,
+		   const domain_enum domain, enum language language,
+		   int *is_a_field_of_this)
 {
   struct symbol *sym;
   const struct language_defn *langdef;
@@ -1354,7 +1347,7 @@ lookup_symbol_aux (const char *name, con
   /* Search specified block and its superiors.  Don't search
      STATIC_BLOCK or GLOBAL_BLOCK.  */
 
-  sym = lookup_symbol_aux_local (name, linkage_name, block, domain);
+  sym = lookup_symbol_aux_local (name, block, domain);
   if (sym != NULL)
     return sym;
 
@@ -1375,7 +1368,7 @@ lookup_symbol_aux (const char *name, con
 
       if (function_block && !dict_empty (BLOCK_DICT (function_block)))
 	sym = lookup_block_symbol (function_block, langdef->la_name_of_this,
-				   NULL, VAR_DOMAIN);
+				   VAR_DOMAIN);
       if (sym)
 	{
 	  struct type *t = sym->type;
@@ -1403,7 +1396,7 @@ lookup_symbol_aux (const char *name, con
   /* Now do whatever is appropriate for LANGUAGE to look
      up static and global variables.  */
 
-  sym = langdef->la_lookup_symbol_nonlocal (name, linkage_name, block, domain);
+  sym = langdef->la_lookup_symbol_nonlocal (name, block, domain);
   if (sym != NULL)
     return sym;
 
@@ -1413,11 +1406,11 @@ lookup_symbol_aux (const char *name, con
      desired name as a file-level static, then do psymtab-to-symtab
      conversion on the fly and return the found symbol. */
 
-  sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, linkage_name, domain);
+  sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, domain);
   if (sym != NULL)
     return sym;
 
-  sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, linkage_name, domain);
+  sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, domain);
   if (sym != NULL)
     return sym;
 
@@ -1428,8 +1421,7 @@ lookup_symbol_aux (const char *name, con
    Don't search STATIC_BLOCK or GLOBAL_BLOCK.  */
 
 static struct symbol *
-lookup_symbol_aux_local (const char *name, const char *linkage_name,
-			 const struct block *block,
+lookup_symbol_aux_local (const char *name, const struct block *block,
 			 const domain_enum domain)
 {
   struct symbol *sym;
@@ -1442,7 +1434,7 @@ lookup_symbol_aux_local (const char *nam
 
   while (block != static_block)
     {
-      sym = lookup_symbol_aux_block (name, linkage_name, block, domain);
+      sym = lookup_symbol_aux_block (name, block, domain);
       if (sym != NULL)
 	return sym;
 
@@ -1485,13 +1477,12 @@ lookup_objfile_from_block (const struct 
    block_found appropriately.  */
 
 struct symbol *
-lookup_symbol_aux_block (const char *name, const char *linkage_name,
-			 const struct block *block,
+lookup_symbol_aux_block (const char *name, const struct block *block,
 			 const domain_enum domain)
 {
   struct symbol *sym;
 
-  sym = lookup_block_symbol (block, name, linkage_name, domain);
+  sym = lookup_block_symbol (block, name, domain);
   if (sym)
     {
       block_found = block;
@@ -1507,7 +1498,6 @@ lookup_symbol_aux_block (const char *nam
 struct symbol *
 lookup_global_symbol_from_objfile (const struct objfile *main_objfile,
 				   const char *name,
-				   const char *linkage_name,
 				   const domain_enum domain)
 {
   const struct objfile *objfile;
@@ -1526,7 +1516,7 @@ lookup_global_symbol_from_objfile (const
         {
           bv = BLOCKVECTOR (s);
           block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-          sym = lookup_block_symbol (block, name, linkage_name, domain);
+          sym = lookup_block_symbol (block, name, domain);
           if (sym)
             {
               block_found = block;
@@ -1538,13 +1528,12 @@ lookup_global_symbol_from_objfile (const
       ALL_OBJFILE_PSYMTABS (objfile, ps)
         {
           if (!ps->readin
-              && lookup_partial_symbol (ps, name, linkage_name,
-                                        1, domain))
+              && lookup_partial_symbol (ps, name, 1, domain))
             {
               s = PSYMTAB_TO_SYMTAB (ps);
               bv = BLOCKVECTOR (s);
               block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-              sym = lookup_block_symbol (block, name, linkage_name, domain);
+              sym = lookup_block_symbol (block, name, domain);
               return fixup_symbol_section (sym, (struct objfile *)objfile);
             }
         }
@@ -1559,8 +1548,7 @@ lookup_global_symbol_from_objfile (const
    static symbols.  */
 
 static struct symbol *
-lookup_symbol_aux_symtabs (int block_index,
-			   const char *name, const char *linkage_name,
+lookup_symbol_aux_symtabs (int block_index, const char *name,
 			   const domain_enum domain)
 {
   struct symbol *sym;
@@ -1573,7 +1561,7 @@ lookup_symbol_aux_symtabs (int block_ind
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, block_index);
-    sym = lookup_block_symbol (block, name, linkage_name, domain);
+    sym = lookup_block_symbol (block, name, domain);
     if (sym)
       {
 	block_found = block;
@@ -1591,7 +1579,6 @@ lookup_symbol_aux_symtabs (int block_ind
 
 static struct symbol *
 lookup_symbol_aux_psymtabs (int block_index, const char *name,
-			    const char *linkage_name,
 			    const domain_enum domain)
 {
   struct symbol *sym;
@@ -1605,13 +1592,12 @@ lookup_symbol_aux_psymtabs (int block_in
   ALL_PSYMTABS (objfile, ps)
   {
     if (!ps->readin
-	&& lookup_partial_symbol (ps, name, linkage_name,
-				  psymtab_index, domain))
+	&& lookup_partial_symbol (ps, name, psymtab_index, domain))
       {
 	s = PSYMTAB_TO_SYMTAB (ps);
 	bv = BLOCKVECTOR (s);
 	block = BLOCKVECTOR_BLOCK (bv, block_index);
-	sym = lookup_block_symbol (block, name, linkage_name, domain);
+	sym = lookup_block_symbol (block, name, domain);
 	if (!sym)
 	  {
 	    /* This shouldn't be necessary, but as a last resort try
@@ -1628,7 +1614,7 @@ lookup_symbol_aux_psymtabs (int block_in
 	    block = BLOCKVECTOR_BLOCK (bv,
 				       block_index == GLOBAL_BLOCK ?
 				       STATIC_BLOCK : GLOBAL_BLOCK);
-	    sym = lookup_block_symbol (block, name, linkage_name, domain);
+	    sym = lookup_block_symbol (block, name, domain);
 	    if (!sym)
 	      error (_("Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n%s may be an inlined function, or may be a template function\n(if a template, try specifying an instantiation: %s<type>)."),
 		     block_index == GLOBAL_BLOCK ? "global" : "static",
@@ -1647,7 +1633,6 @@ lookup_symbol_aux_psymtabs (int block_in
 
 struct symbol *
 basic_lookup_symbol_nonlocal (const char *name,
-			      const char *linkage_name,
 			      const struct block *block,
 			      const domain_enum domain)
 {
@@ -1681,11 +1666,11 @@ basic_lookup_symbol_nonlocal (const char
      than that one, so I don't think we should worry about that for
      now.  */
 
-  sym = lookup_symbol_static (name, linkage_name, block, domain);
+  sym = lookup_symbol_static (name, block, domain);
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_global (name, linkage_name, block, domain);
+  return lookup_symbol_global (name, block, domain);
 }
 
 /* Lookup a symbol in the static block associated to BLOCK, if there
@@ -1693,14 +1678,13 @@ basic_lookup_symbol_nonlocal (const char
 
 struct symbol *
 lookup_symbol_static (const char *name,
-		      const char *linkage_name,
 		      const struct block *block,
 		      const domain_enum domain)
 {
   const struct block *static_block = block_static_block (block);
 
   if (static_block != NULL)
-    return lookup_symbol_aux_block (name, linkage_name, static_block, domain);
+    return lookup_symbol_aux_block (name, static_block, domain);
   else
     return NULL;
 }
@@ -1710,7 +1694,6 @@ lookup_symbol_static (const char *name,
 
 struct symbol *
 lookup_symbol_global (const char *name,
-		      const char *linkage_name,
 		      const struct block *block,
 		      const domain_enum domain)
 {
@@ -1720,15 +1703,15 @@ lookup_symbol_global (const char *name,
   /* Call library-specific lookup procedure.  */
   objfile = lookup_objfile_from_block (block);
   if (objfile != NULL)
-    sym = solib_global_lookup (objfile, name, linkage_name, domain);
+    sym = solib_global_lookup (objfile, name, domain);
   if (sym != NULL)
     return sym;
 
-  sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name, domain);
+  sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, domain);
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name, domain);
+  return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, domain);
 }
 
 int
@@ -1752,14 +1735,11 @@ symbol_matches_domain (enum language sym
 }
 
 /* Look, in partial_symtab PST, for symbol whose natural name is NAME.
-   If LINKAGE_NAME is non-NULL, check in addition that the symbol's
-   linkage name matches it.  Check the global symbols if GLOBAL, the
-   static symbols if not */
+   Check the global symbols if GLOBAL, the static symbols if not. */
 
 struct partial_symbol *
 lookup_partial_symbol (struct partial_symtab *pst, const char *name,
-		       const char *linkage_name, int global,
-		       domain_enum domain)
+		       int global, domain_enum domain)
 {
   struct partial_symbol *temp;
   struct partial_symbol **start, **psym;
@@ -1811,9 +1791,7 @@ lookup_partial_symbol (struct partial_sy
 	internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
 
       while (top <= real_top
-	     && (linkage_name != NULL
-		 ? strcmp (SYMBOL_LINKAGE_NAME (*top), linkage_name) == 0
-		 : SYMBOL_MATCHES_SEARCH_NAME (*top,name)))
+	     && SYMBOL_MATCHES_SEARCH_NAME (*top, name))
 	{
 	  if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
 				     SYMBOL_DOMAIN (*top), domain))
@@ -1830,15 +1808,9 @@ lookup_partial_symbol (struct partial_sy
       for (psym = start; psym < start + length; psym++)
 	{
 	  if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
-				     SYMBOL_DOMAIN (*psym), domain))
-	    {
-	      if (linkage_name != NULL
-		  ? strcmp (SYMBOL_LINKAGE_NAME (*psym), linkage_name) == 0
-		  : SYMBOL_MATCHES_SEARCH_NAME (*psym, name))
-		{
-		  return (*psym);
-		}
-	    }
+				     SYMBOL_DOMAIN (*psym), domain)
+	      && SYMBOL_MATCHES_SEARCH_NAME (*psym, name))
+	    return (*psym);
 	}
     }
 
@@ -1880,7 +1852,7 @@ basic_lookup_transparent_type (const cha
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-    sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
     if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
       {
 	return SYMBOL_TYPE (sym);
@@ -1889,13 +1861,12 @@ basic_lookup_transparent_type (const cha
 
   ALL_PSYMTABS (objfile, ps)
   {
-    if (!ps->readin && lookup_partial_symbol (ps, name, NULL,
-					      1, STRUCT_DOMAIN))
+    if (!ps->readin && lookup_partial_symbol (ps, name, 1, STRUCT_DOMAIN))
       {
 	s = PSYMTAB_TO_SYMTAB (ps);
 	bv = BLOCKVECTOR (s);
 	block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-	sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+	sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
 	if (!sym)
 	  {
 	    /* This shouldn't be necessary, but as a last resort
@@ -1904,7 +1875,7 @@ basic_lookup_transparent_type (const cha
 	     * the psymtab gets it wrong in some cases.
 	     */
 	    block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-	    sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+	    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
 	    if (!sym)
 	      error (_("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
 %s may be an inlined function, or may be a template function\n\
@@ -1928,7 +1899,7 @@ basic_lookup_transparent_type (const cha
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-    sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
     if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
       {
 	return SYMBOL_TYPE (sym);
@@ -1937,12 +1908,12 @@ basic_lookup_transparent_type (const cha
 
   ALL_PSYMTABS (objfile, ps)
   {
-    if (!ps->readin && lookup_partial_symbol (ps, name, NULL, 0, STRUCT_DOMAIN))
+    if (!ps->readin && lookup_partial_symbol (ps, name, 0, STRUCT_DOMAIN))
       {
 	s = PSYMTAB_TO_SYMTAB (ps);
 	bv = BLOCKVECTOR (s);
 	block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-	sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+	sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
 	if (!sym)
 	  {
 	    /* This shouldn't be necessary, but as a last resort
@@ -1951,7 +1922,7 @@ basic_lookup_transparent_type (const cha
 	     * the psymtab gets it wrong in some cases.
 	     */
 	    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-	    sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+	    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
 	    if (!sym)
 	      error (_("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
 %s may be an inlined function, or may be a template function\n\
@@ -1978,7 +1949,7 @@ find_main_psymtab (void)
 
   ALL_PSYMTABS (objfile, pst)
   {
-    if (lookup_partial_symbol (pst, main_name (), NULL, 1, VAR_DOMAIN))
+    if (lookup_partial_symbol (pst, main_name (), 1, VAR_DOMAIN))
       {
 	return (pst);
       }
@@ -1996,14 +1967,10 @@ find_main_psymtab (void)
    search on the symbols.  Each symbol which is marked as being a ObjC/C++
    symbol (language_cplus or language_objc set) has both the encoded and
    non-encoded names tested for a match.
-
-   If LINKAGE_NAME is non-NULL, verify that any symbol we find has this
-   particular mangled name.
 */
 
 struct symbol *
 lookup_block_symbol (const struct block *block, const char *name,
-		     const char *linkage_name,
 		     const domain_enum domain)
 {
   struct dict_iterator iter;
@@ -2016,9 +1983,7 @@ lookup_block_symbol (const struct block 
 	   sym = dict_iter_name_next (name, &iter))
 	{
 	  if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
-				     SYMBOL_DOMAIN (sym), domain)
-	      && (linkage_name != NULL
-		  ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1))
+				     SYMBOL_DOMAIN (sym), domain))
 	    return sym;
 	}
       return NULL;
@@ -2038,9 +2003,7 @@ lookup_block_symbol (const struct block 
 	   sym = dict_iter_name_next (name, &iter))
 	{
 	  if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
-				     SYMBOL_DOMAIN (sym), domain)
-	      && (linkage_name != NULL
-		  ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1))
+				     SYMBOL_DOMAIN (sym), domain))
 	    {
 	      sym_found = sym;
 	      if (!SYMBOL_IS_ARGUMENT (sym))
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.146
diff -u -p -r1.146 symtab.h
--- symtab.h	27 Jan 2010 00:15:59 -0000	1.146
+++ symtab.h	28 Jan 2010 23:30:24 -0000
@@ -172,9 +172,6 @@ extern CORE_ADDR symbol_overlayed_addres
 #define SYMBOL_SECTION(symbol)		(symbol)->ginfo.section
 #define SYMBOL_OBJ_SECTION(symbol)	(symbol)->ginfo.obj_section
 
-#define SYMBOL_CPLUS_DEMANGLED_NAME(symbol)	\
-  (symbol)->ginfo.language_specific.cplus_specific.demangled_name
-
 /* Initializes the language dependent portion of a symbol
    depending upon the language for the symbol. */
 #define SYMBOL_INIT_LANGUAGE_SPECIFIC(symbol,language) \
@@ -994,7 +991,6 @@ extern struct symbol *lookup_symbol (con
    that can't think of anything better to do.  */
 
 extern struct symbol *basic_lookup_symbol_nonlocal (const char *,
-						    const char *,
 						    const struct block *,
 						    const domain_enum);
 
@@ -1005,7 +1001,6 @@ extern struct symbol *basic_lookup_symbo
    is one; do nothing if BLOCK is NULL or a global block.  */
 
 extern struct symbol *lookup_symbol_static (const char *name,
-					    const char *linkage_name,
 					    const struct block *block,
 					    const domain_enum domain);
 
@@ -1013,7 +1008,6 @@ extern struct symbol *lookup_symbol_stat
    necessary).  */
 
 extern struct symbol *lookup_symbol_global (const char *name,
-					    const char *linkage_name,
 					    const struct block *block,
 					    const domain_enum domain);
 
@@ -1022,21 +1016,18 @@ extern struct symbol *lookup_symbol_glob
    will fix up the symbol if necessary.  */
 
 extern struct symbol *lookup_symbol_aux_block (const char *name,
-					       const char *linkage_name,
 					       const struct block *block,
 					       const domain_enum domain);
 
 /* Lookup a partial symbol.  */
 
 extern struct partial_symbol *lookup_partial_symbol (struct partial_symtab *,
-						     const char *,
 						     const char *, int,
 						     domain_enum);
 
 /* lookup a symbol by name, within a specified block */
 
 extern struct symbol *lookup_block_symbol (const struct block *, const char *,
-					   const char *,
 					   const domain_enum);
 
 /* lookup a [struct, union, enum] by name, within a specified block */
@@ -1372,7 +1363,6 @@ extern /*const */ char *main_name (void)
 /* Check global symbols in objfile.  */
 struct symbol *lookup_global_symbol_from_objfile (const struct objfile *objfile,
 						  const char *name,
-						  const char *linkage_name,
 						  const domain_enum domain);
 
 extern struct symtabs_and_lines
Index: typeprint.h
===================================================================
RCS file: /cvs/src/src/gdb/typeprint.h,v
retrieving revision 1.9
diff -u -p -r1.9 typeprint.h
--- typeprint.h	1 Jan 2010 07:31:43 -0000	1.9
+++ typeprint.h	28 Jan 2010 23:30:24 -0000
@@ -20,10 +20,13 @@
 #ifndef TYPEPRINT_H
 #define TYPEPRINT_H
 
+enum language;
 struct ui_file;
 
 void print_type_scalar (struct type * type, LONGEST, struct ui_file *);
 
 void c_type_print_varspec_suffix (struct type *, struct ui_file *, int,
 				  int, int);
+
+void c_type_print_args (struct type *, struct ui_file *, int, enum language);
 #endif
Index: ui-file.c
===================================================================
RCS file: /cvs/src/src/gdb/ui-file.c,v
retrieving revision 1.20
diff -u -p -r1.20 ui-file.c
--- ui-file.c	1 Jan 2010 07:31:43 -0000	1.20
+++ ui-file.c	28 Jan 2010 23:30:24 -0000
@@ -22,6 +22,7 @@
 
 #include "defs.h"
 #include "ui-file.h"
+#include "gdb_obstack.h"
 #include "gdb_string.h"
 #include "gdb_select.h"
 
@@ -264,7 +265,7 @@ set_ui_file_data (struct ui_file *file, 
 }
 
 /* ui_file utility function for converting a ``struct ui_file'' into
-   a memory buffer''. */
+   a memory buffer. */
 
 struct accumulated_ui_file
 {
@@ -298,6 +299,23 @@ ui_file_xstrdup (struct ui_file *file, l
     *length = acc.length;
   return acc.buffer;
 }
+
+static void
+do_ui_file_obsavestring (void *context, const char *buffer, long length)
+{
+  struct obstack *obstack = (struct obstack *) context;
+  obstack_grow (obstack, buffer, length);
+}
+
+char *
+ui_file_obsavestring (struct ui_file *file, struct obstack *obstack,
+		      long *length)
+{
+  ui_file_put (file, do_ui_file_obsavestring, obstack);
+  *length = obstack_object_size (obstack);
+  obstack_1grow (obstack, '\0');
+  return obstack_finish (obstack);
+}
 \f
 /* A pure memory based ``struct ui_file'' that can be used an output
    buffer. The buffers accumulated contents are available via
Index: ui-file.h
===================================================================
RCS file: /cvs/src/src/gdb/ui-file.h,v
retrieving revision 1.11
diff -u -p -r1.11 ui-file.h
--- ui-file.h	1 Jan 2010 07:31:43 -0000	1.11
+++ ui-file.h	28 Jan 2010 23:30:24 -0000
@@ -20,6 +20,7 @@
 #ifndef UI_FILE_H
 #define UI_FILE_H
 
+struct obstack;
 struct ui_file;
 
 /* Create a generic ui_file object with null methods. */
@@ -78,7 +79,10 @@ extern void ui_file_put (struct ui_file 
    minus that appended NUL. */
 extern char *ui_file_xstrdup (struct ui_file *file, long *length);
 
-
+/* Similar to ui_file_xstrdup, but return a new string allocated on
+   OBSTACK.  */
+extern char *ui_file_obsavestring (struct ui_file *file,
+				   struct obstack *obstack, long *length);
 
 extern long ui_file_read (struct ui_file *file, char *buf, long length_buf);
 
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.233
diff -u -p -r1.233 valops.c
--- valops.c	26 Jan 2010 16:47:34 -0000	1.233
+++ valops.c	28 Jan 2010 23:30:25 -0000
@@ -2328,12 +2328,25 @@ find_overload_match (struct type **arg_t
   if (method)
     {
       gdb_assert (obj);
+
+      /* OBJ may be a pointer value rather than the object itself.  */
+      obj = coerce_ref (obj);
+      while (TYPE_CODE (check_typedef (value_type (obj))) == TYPE_CODE_PTR)
+	obj = coerce_ref (value_ind (obj));
       obj_type_name = TYPE_NAME (value_type (obj));
-      /* Hack: evaluate_subexp_standard often passes in a pointer
-         value rather than the object itself, so try again.  */
-      if ((!obj_type_name || !*obj_type_name) 
-	  && (TYPE_CODE (value_type (obj)) == TYPE_CODE_PTR))
-	obj_type_name = TYPE_NAME (TYPE_TARGET_TYPE (value_type (obj)));
+
+      /* First check whether this is a data member, e.g. a pointer to
+	 a function.  */
+      if (TYPE_CODE (check_typedef (value_type (obj))) == TYPE_CODE_STRUCT)
+	{
+	  *valp = search_struct_field (name, obj, 0,
+				       check_typedef (value_type (obj)), 0);
+	  if (*valp)
+	    {
+	      *staticp = 1;
+	      return 0;
+	    }
+	}
 
       fns_ptr = value_find_oload_method_list (&temp, name, 
 					      0, &num_fns, 
@@ -2353,16 +2366,29 @@ find_overload_match (struct type **arg_t
     }
   else
     {
-      const char *qualified_name = SYMBOL_CPLUS_DEMANGLED_NAME (fsym);
+      const char *qualified_name = SYMBOL_NATURAL_NAME (fsym);
+
+      /* If we have a function with a C++ name, try to extract just
+	 the function part.  Do not try this for non-functions (e.g.
+	 function pointers).  */
+      if (qualified_name
+	  && TYPE_CODE (check_typedef (SYMBOL_TYPE (fsym))) == TYPE_CODE_FUNC)
+	{
+	  func_name = cp_func_name (qualified_name);
+
+	  /* If cp_func_name did not remove anything, the name of the
+	     symbol did not include scope or argument types - it was
+	     probably a C-style function.  */
+	  if (func_name && strcmp (func_name, qualified_name) == 0)
+	    {
+	      xfree (func_name);
+	      func_name = NULL;
+	    }
+	}
 
-      /* If we have a C++ name, try to extract just the function
-	 part.  */
-      if (qualified_name)
-	func_name = cp_func_name (qualified_name);
-
-      /* If there was no C++ name, this must be a C-style function.
-	 Just return the same symbol.  Do the same if cp_func_name
-	 fails for some reason.  */
+      /* If there was no C++ name, this must be a C-style function or
+	 not a function at all.  Just return the same symbol.  Do the
+	 same if cp_func_name fails for some reason.  */
       if (func_name == NULL)
         {
 	  *symp = fsym;
@@ -3096,7 +3122,7 @@ value_maybe_namespace_elt (const struct 
   struct symbol *sym;
   struct value *result;
 
-  sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
+  sym = cp_lookup_symbol_namespace(namespace_name, name,
 				    get_selected_block (0), 
 				    VAR_DOMAIN, 1);
 
@@ -3240,7 +3266,7 @@ value_of_local (const char *name, int co
 
   /* Calling lookup_block_symbol is necessary to get the LOC_REGISTER
      symbol instead of the LOC_ARG one (if both exist).  */
-  sym = lookup_block_symbol (b, name, NULL, VAR_DOMAIN);
+  sym = lookup_block_symbol (b, name, VAR_DOMAIN);
   if (sym == NULL)
     {
       if (complain)
Index: testsuite/gdb.cp/cp-relocate.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/cp-relocate.exp,v
retrieving revision 1.7
diff -u -p -r1.7 cp-relocate.exp
--- testsuite/gdb.cp/cp-relocate.exp	1 Jan 2010 07:32:01 -0000	1.7
+++ testsuite/gdb.cp/cp-relocate.exp	28 Jan 2010 23:30:25 -0000
@@ -30,7 +30,7 @@ proc get_func_address { func } {
     global gdb_prompt hex
 
     set rfunc [string_to_regexp $func]
-    gdb_test_multiple "print '${func}'" "get address of ${func}" {
+    gdb_test_multiple "print ${func}" "get address of ${func}" {
 	-re "\\\$\[0-9\]+ = \\{.*\\} (0|($hex) <${rfunc}>)\[\r\n\]+${gdb_prompt} $" {
 	    # $1 = {int ()} 0x24 <function_bar>
 	    # But if the function is at zero, the name may be omitted.
@@ -130,7 +130,7 @@ gdb_test "add-symbol-file ${binfile} 0 -
 	"y"
 
 # Make sure the function addresses were updated.
-gdb_test "break *'$func1_name'" \
+gdb_test "break *$func1_name" \
     "Breakpoint $decimal at 0x1....: file .*"
-gdb_test "break *'$func2_name'" \
+gdb_test "break *$func2_name" \
     "Breakpoint $decimal at 0x2....: file .*"
Index: testsuite/gdb.cp/cpexprs.cc
===================================================================
RCS file: testsuite/gdb.cp/cpexprs.cc
diff -N testsuite/gdb.cp/cpexprs.cc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/cpexprs.cc	28 Jan 2010 23:30:25 -0000
@@ -0,0 +1,431 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2008, 2009, 2010 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/>.
+
+   Please email any bugs, comments, and/or additions to this file to:
+   bug-gdb@gnu.org  */
+
+#include <stdlib.h>
+#include <iostream>
+
+// Forward decls
+class base;
+class derived;
+
+// A simple template with specializations
+template <typename T>
+class tclass
+{
+public:
+  void do_something () { } // tclass<T>::do_something
+};
+
+template <>
+void tclass<char>::do_something () { } // tclass<char>::do_something
+
+template <>
+void tclass<int>::do_something () { } // tclass<int>::do_something
+
+template<>
+void tclass<long>::do_something () { } // tclass<long>::do_something
+
+template<>
+void tclass<short>::do_something () { } // tclass<short>::do_something
+
+// A simple template with multiple template parameters
+template <class A, class B, class C, class D, class E>
+void flubber (void) // flubber
+{
+  A a;
+  B b;
+  C c;
+  D d;
+  E e;
+
+  ++a;
+  ++b;
+  ++c;
+  ++d;
+  ++e;
+}
+
+// Some contrived policies
+template <class T>
+struct operation_1
+{
+  static void function (void) { } // operation_1<T>::function
+};
+
+template <class T>
+struct operation_2
+{
+  static void function (void) { } // operation_2<T>::function
+};
+
+template <class T>
+struct operation_3
+{
+  static void function (void) { } // operation_3<T>::function
+};
+
+template <class T>
+struct operation_4
+{
+  static void function (void) { } // operation_4<T>::function
+};
+
+// A policy-based class w/ and w/o default policy
+template <class T, class Policy>
+class policy : public Policy
+{
+public:
+  policy (T obj) : obj_ (obj) { } // policy<T, Policy>::policy
+
+private:
+  T obj_;
+};
+
+template <class T, class Policy = operation_1<T> >
+class policyd : public Policy
+{
+public:
+  policyd (T obj) : obj_ (obj) { } // policyd<T, Policy>::policyd
+  ~policyd (void) { } // policyd<T, Policy>::~policyd
+
+private:
+  T obj_;
+};
+
+typedef policy<int, operation_1<void*> > policy1;
+typedef policy<int, operation_2<void*> > policy2;
+typedef policy<int, operation_3<void*> > policy3;
+typedef policy<int, operation_4<void*> > policy4;
+
+typedef policyd<int> policyd1;
+typedef policyd<long> policyd2;
+typedef policyd<char> policyd3;
+typedef policyd<base> policyd4;
+typedef policyd<tclass<int> > policyd5;
+
+class fluff { };
+static fluff *g_fluff = new fluff ();
+
+class base
+{
+protected:
+  int foo_;
+
+public:
+  base (void) : foo_ (42) { } // base::base(void)
+  base (int foo) : foo_ (foo) { } // base::base(int)
+  ~base (void) { } // base::~base
+
+  // Some overloaded methods
+  int overload (void) const { return 0; } // base::overload(void) const
+  int overload (int i) const { return 1; } // base::overload(int) const
+  int overload (short s) const { return 2; } // base::overload(short) const
+  int overload (long l) const { return 3; } // base::overload(long) const
+  int overload (char* a) const { return 4; } // base::overload(char*) const
+  int overload (base& b) const { return 5; } // base::overload(base&) const
+
+  // Operators
+  int operator+ (base const& o) const // base::operator+
+  { return foo_ + o.foo_; }
+
+  base operator++ (void) // base::operator++
+  { ++foo_; return *this; }
+
+  base operator+=(base const& o) // base::operator+=
+  { foo_ += o.foo_; return *this; }
+
+  int operator- (base const& o) const // base::operator-
+  { return foo_ - o.foo_; }
+
+  base operator-- (void) // base::operator--
+  { --foo_; return *this; }
+
+  base operator-= (base const& o) // base::operator-=
+  { foo_ -= o.foo_; return *this; }
+
+  int operator* (base const& o) const // base::operator*
+  { return foo_ * o.foo_; }
+
+  base operator*= (base const& o) // base::operator*=
+  { foo_ *= o.foo_; return *this; }
+
+  int operator/ (base const& o) const // base::operator/
+  { return foo_ / o.foo_; }
+
+  base operator/= (base const& o) // base::operator/=
+  { foo_ /= o.foo_; return *this; }
+
+  int operator% (base const& o) const // base::operator%
+  { return foo_ % o.foo_; }
+  
+  base operator%= (base const& o) // base::operator%=
+  { foo_ %= o.foo_; return *this; }
+
+  bool operator< (base const& o) const // base::operator<
+  { return foo_ < o.foo_; }
+
+  bool operator<= (base const& o) const // base::operator<=
+  { return foo_ <= o.foo_; }
+
+  bool operator> (base const& o) const // base::operator>
+  { return foo_ > o.foo_; }
+
+  bool operator>= (base const& o) const // base::operator>=
+  { return foo_ >= o.foo_; }
+
+  bool operator!= (base const& o) const // base::operator!=
+  { return foo_ != o.foo_; }
+
+  bool operator== (base const& o) const // base::operator==
+  { return foo_ == o.foo_; }
+
+  bool operator! (void) const // base::operator!
+  { return !foo_; }
+
+  bool operator&& (base const& o) const // base::operator&&
+  { return foo_ && o.foo_; }
+
+  bool operator|| (base const& o) const // base::operator||
+  { return foo_ || o.foo_; }
+
+  int operator<< (int value) const // base::operator<<
+  { return foo_  << value; }
+
+  base operator<<= (int value) // base::operator<<=
+  { foo_ <<= value; return *this; }
+
+  int operator>> (int value) const // base::operator>>
+  { return foo_  >> value; }
+
+  base operator>>= (int value) // base::operator>>=
+  { foo_ >>= value; return *this; }
+
+  int operator~ (void) const // base::operator~
+  { return ~foo_; }
+
+  int operator& (base const& o) const // base::operator&
+  { return foo_ & o.foo_; }
+
+  base operator&= (base const& o) // base::operator&=
+  { foo_ &= o.foo_; return *this; }
+
+  int operator| (base const& o) const // base::operator|
+  { return foo_ | o.foo_; }
+
+  base operator|= (base const& o) // base::operator|=
+  { foo_ |= o.foo_; return *this; }
+  
+  int operator^ (base const& o) const // base::operator^
+  { return foo_ ^ o.foo_; }
+
+  base operator^= (base const& o) // base::operator^=
+  { foo_ ^= o.foo_; return *this; }
+
+  base operator= (base const& o) // base::operator=
+  { foo_ = o.foo_; return *this; }
+
+  void operator() (void) const // base::operator()
+  { return; }
+
+  int operator[] (int idx) const // base::operator[]
+  { return idx; }
+
+  void* operator new (size_t size) throw () // base::operator new
+  { return malloc (size); }
+
+  void operator delete (void* ptr) // base::operator delete
+  { free (ptr); }
+
+  void* operator new[] (size_t size) throw () // base::operator new[]
+  { return malloc (size); }
+
+  void operator delete[] (void* ptr) // base::operator delete[]
+  { free (ptr); }
+
+  base const* operator-> (void) const // base::opeartor->
+  { return this; }
+
+  int operator->* (base const& b) const // base::operator->*
+  {  return foo_ * b.foo_; }
+
+  operator char* () const { return const_cast<char*> ("hello"); } // base::operator char*
+  operator int () const { return 21; } // base::operator int
+  operator fluff* () const { return new fluff (); } // base::operator fluff*
+  operator fluff** () const { return &g_fluff; } // base::operator fluff**
+};
+
+class base1 : public virtual base
+{
+public:
+  base1 (void) : foo_ (21) { } // base1::base1(void)
+  base1 (int a) : foo_(a) { } // base1::base1(int)
+  void a_function (void) const { } // base1::a_function
+
+protected:
+  int foo_;
+};
+
+class base2 : public virtual base
+{
+public:
+  base2 () : foo_ (3) { } // base2::base2
+
+protected:
+  void a_function (void) const { } // base2::a_function
+  int foo_;
+};
+
+class derived : public base1, public base2
+{
+  public:
+  derived(void) : foo_ (4) { } // derived::derived
+  void a_function (void) const // derived::a_function
+  { 
+    this->base1::a_function ();
+    this->base2::a_function ();
+  }
+
+  protected:
+  int foo_;
+};
+
+int
+main (int argc, char* argv[]) // main
+{ // main
+  derived d;
+  void (derived::*pfunc) (void) const = &derived::a_function;
+  (d.*pfunc) ();
+
+  base a (1), b (3), c (8);
+  (void) a.overload ();
+  (void) a.overload (static_cast<int> (0));
+  (void) a.overload (static_cast<short> (0));
+  (void) a.overload (static_cast<long> (0));
+  (void) a.overload (static_cast<char*> (0));
+  (void) a.overload (a);
+
+  int r;
+  r = b + c;
+  ++a;
+  a += b;
+  r = b - c;
+  --a;
+  a -= b;
+  r = b * c;
+  a *= b;
+  r = b / c;
+  a /= b;
+  r = b % c;
+  a %= b;
+  bool x = (b < c);
+  x = (b <= c);
+  x = (b > c);
+  x = (b >= c);
+  x = (b != c);
+  x = (b == c);
+  x = (!b);
+  x = (b && c);
+  x = (b || c);
+  r = b << 2;
+  a <<= 1;
+  r = b >> 2;
+  a >>= 1;
+  r = ~b;
+  r = b & c;
+  a &= c;
+  r = b | c;
+  a |= c;
+  r = b ^ c;
+  a ^= c;
+  a = c;
+  a ();
+  int i = a[3];
+  derived* f = new derived ();
+  derived* g = new derived[3];
+  delete f;
+  delete[] g;
+  a->overload ();
+  r = a->*b;
+
+  tclass<char> char_tclass;
+  tclass<int> int_tclass;
+  tclass<short> short_tclass;
+  tclass<long> long_tclass;
+  tclass<base> base_tclass;
+  char_tclass.do_something ();
+  int_tclass.do_something ();
+  short_tclass.do_something ();
+  long_tclass.do_something ();
+  base_tclass.do_something ();
+
+  flubber<int, int, int, int, int> ();
+  flubber<int, int, int, int, short> ();
+  flubber<int, int, int, int, long> ();
+  flubber<int, int, int, int, char> ();
+  flubber<int, int, int, short, int> ();
+  flubber<int, int, int, short, short> ();
+  flubber<int, int, int, short, long> ();
+  flubber<int, int, int, short, char> ();
+  flubber<int, int, int, long, int> ();
+  flubber<int, int, int, long, short> ();
+  flubber<int, int, int, long, long> ();
+  flubber<int, int, int, long, char> ();
+  flubber<int, int, int, char, int> ();
+  flubber<int, int, int, char, short> ();
+  flubber<int, int, int, char, long> ();
+  flubber<int, int, int, char, char> ();
+  flubber<int, int, short, int, int> ();
+  flubber<int, int, short, int, short> ();
+  flubber<int, int, short, int, long> ();
+  flubber<int, int, short, int, char> ();
+  flubber<int, int, short, short, int> ();
+  flubber<short, int, short, int, short> ();
+  flubber<long, short, long, short, long> ();
+
+  policy1 p1 (1);
+  p1.function ();
+  policy2 p2 (2);
+  p2.function ();
+  policy3 p3 (3);
+  p3.function ();
+  policy4 p4 (4);
+  p4.function ();
+
+  policyd1 pd1 (5);
+  pd1.function ();
+  policyd2 pd2 (6);
+  pd2.function ();
+  policyd3 pd3 (7);
+  pd3.function ();
+  policyd4 pd4 (d);
+  pd4.function ();
+  policyd5 pd5 (int_tclass);
+  pd5.function ();
+
+  base1 b1 (3);
+
+  r = a;
+  char* str = a;
+  fluff* flp = a;
+  fluff** flpp = a;
+}
+
Index: testsuite/gdb.cp/cpexprs.exp
===================================================================
RCS file: testsuite/gdb.cp/cpexprs.exp
diff -N testsuite/gdb.cp/cpexprs.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ testsuite/gdb.cp/cpexprs.exp	28 Jan 2010 23:30:25 -0000
@@ -0,0 +1,724 @@
+# cpexprs.exp - C++ expressions tests
+#
+# Copyright 2008, 2009, 2010 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.
+
+# A helper proc which sets a breakpoint at FUNC and attempts to
+# run to the breakpoint.
+proc test_breakpoint {func} {
+    global DEC
+
+    # Restart every time
+    if {![runto_main]} {
+	perror "could not run to main when attempting to break at $func"
+    } else {
+	gdb_breakpoint "$func"
+	set i [expr {[string last : $func] + 1}]
+	set efunc [string_to_regexp [string range $func $i end]]
+	gdb_test "continue" \
+	    "Continuing.\r\n\r\nBreakpoint $DEC+,.*$efunc.*" \
+	    "continue to $func"
+    }
+}
+
+# Add a function to the list of tested functions
+# FUNC is the name of the function (which will be passed to gdb commands)
+# TYPE is the type of the function, as expected from the "print" command
+# PRINT is the name of the function, as expected result of the print command
+#  *OR* "-", indicating that FUNC should be used (needed for virtual/inherited
+#   funcs)
+# LST is either the expected result of the list command (the comment from
+#  the source code) *OR* "-", in which case FUNC will be used
+#
+# Usage:
+# add NAME TYPE PRINT LST
+# add NAME TYPE PRINT -
+proc add {func type print lst} {
+    global all_functions CONVAR ADDR
+
+    set all_functions($func,type) $type
+    if {$print == "-"} {
+	set print $func
+    }
+
+    # An exception: since gdb canonicalizes C++ output,
+    # "(void)" must be mutated to "()".
+    regsub {\(void\)} $print {()} print
+
+    set all_functions($func,print) \
+	"$CONVAR = {[string_to_regexp $type]} $ADDR <[string_to_regexp $print].*>"
+    if {$lst == "-"} {
+	set lst "$func"
+    }
+    set all_functions($func,list) ".*// [string_to_regexp $lst]"
+}
+
+proc get {func cmd} {
+    global all_functions
+    return $all_functions($func,$cmd)
+}
+
+# Returns a list of function names for a given command
+proc get_functions {cmd} {
+    global all_functions
+    set result {}
+    foreach i [array names all_functions *,$cmd] {
+	if {$all_functions($i) != ""} {
+	    set idx [string last , $i]
+	    if {$idx != -1} {
+		lappend result [string range $i 0 [expr {$idx - 1}]]
+	    }
+	}
+    }
+
+    return [lsort $result]
+}
+
+# Some convenience variables for this test
+set DEC {[0-9]}; # a decimal number
+set HEX {[0-9a-fA-F]}; # a hexidecimal number
+set CONVAR "\\\$$DEC+"; # convenience variable regexp
+set ADDR "0x$HEX+"; # address
+
+# An array of functions/methods that we are testing...
+# Each element consists is indexed by NAME,COMMAND, where
+# NAME is the function name and COMMAND is the gdb command that
+# we are testing. The value of the array for any index pair is
+# the expected result of running COMMAND with the NAME as argument.
+
+# The array holding all functions/methods to test. Valid subindexes
+# are (none need character escaping -- "add" will take care of that):
+
+# add name type print_name list
+# NAME,type: value is type of function 
+# NAME,print: value is print name of function (careful w/inherited/virtual!)
+# NAME,list: value is comment in source code on first line of function
+#   (without the leading "//")
+array set all_functions {}
+
+# "Normal" functions/methods
+add {main} \
+    {int (int, char **)} \
+    - \
+    -
+add {derived::a_function} \
+    {void (const derived * const)} \
+    - \
+    -
+add {base1::a_function} \
+    {void (const base1 * const)} \
+    - \
+    -
+add {base2::a_function} \
+    {void (const base2 * const)} \
+    - \
+    -
+
+# Constructors
+
+# On targets using the ARM EABI, the constructor is expected to return
+# "this".
+proc ctor { type arglist } {
+    if { [istarget arm*-*eabi*] } {
+	set ret "$type *"
+    } else {
+	set ret "void "
+    }
+    if { $arglist != "" } {
+	set arglist ", $arglist"
+    }
+    return "${ret}($type * const$arglist)"
+}
+
+add {derived::derived} \
+    [ctor derived ""] \
+    - \
+    -
+add {base1::base1(void)} \
+    [ctor base1 "const void ** const"] \
+    - \
+    -
+add {base1::base1(int)} \
+    [ctor base1 "int"] \
+    - \
+    -
+add {base2::base2} \
+    [ctor base2 "const void ** const"] \
+    - \
+    -
+add {base::base(void)} \
+    [ctor base ""] \
+    - \
+    -
+add {base::base(int)} \
+    [ctor base "int"] \
+    - \
+    -
+
+# Destructors
+
+# On targets using the ARM EABI, some destructors are expected
+# to return "this".  Others are void.  For internal reasons,
+# GCC returns void * instead of $type *; RealView appears to do
+# the same.
+proc dtor { type } {
+    if { [istarget arm*-*eabi*] } {
+	set ret "void *"
+    } else {
+	set ret "void "
+    }
+    return "${ret}($type * const)"
+}
+
+add {base::~base} \
+    [dtor base] \
+    - \
+    -
+
+# Overloaded methods (all are const -- we try to use the void
+# method with and without specifying "const")
+add {base::overload(void)} \
+    {int (const base * const)} \
+    - \
+    {base::overload(void) const}
+add {base::overload(void) const} \
+    {int (const base * const)} \
+    - \
+    {base::overload(void) const}
+add {base::overload(int) const} \
+    {int (const base * const, int)} \
+    - \
+    -
+add {base::overload(short) const} \
+    {int (const base * const, short)} \
+    - \
+    -
+add {base::overload(long) const} \
+    {int (const base * const, long)} \
+    - \
+    -
+add {base::overload(char*) const} \
+    {int (const base * const, char *)} \
+    - \
+    -
+add {base::overload(base&) const} \
+    {int (const base * const, base &)} \
+    - \
+    -
+
+# Operators
+add {base::operator+} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator++} \
+    {base (base * const)} \
+    - \
+    -
+add {base::operator+=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator-} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator--} \
+    {base (base * const)} \
+    - \
+    -
+add {base::operator-=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator*} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator*=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator/} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator/=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator%} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator%=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator<} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator<=} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator>} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator>=} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator!=} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator==} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator!} \
+    {bool (const base * const)} \
+    - \
+    -
+add {base::operator&&} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator||} \
+    {bool (const base * const, const base &)} \
+    - \
+    -
+add {base::operator<<} \
+    {int (const base * const, int)} \
+    - \
+    -
+add {base::operator<<=} \
+    {base (base * const, int)} \
+    - \
+    -
+add {base::operator>>} \
+    {int (const base * const, int)} \
+    - \
+    -
+add {base::operator>>=} \
+    {base (base * const, int)} \
+    - \
+    -
+add {base::operator~} \
+    {int (const base * const)} \
+    - \
+    -
+add {base::operator&} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator&=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator|} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator|=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator^} \
+    {int (const base * const, const base &)} \
+    - \
+    -
+add {base::operator^=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator=} \
+    {base (base * const, const base &)} \
+    - \
+    -
+add {base::operator()} \
+    {void (const base * const)} \
+    - \
+    -
+add {base::operator[]} \
+    {int (const base * const, int)} \
+    - \
+    -
+add {base::operator new} \
+    {void *(size_t)} \
+    - \
+    -
+add {base::operator delete} \
+    {void (void *)} \
+    - \
+    -
+add {base::operator new[]} \
+    {void *(size_t)} \
+    - \
+    -
+add {base::operator delete[]} \
+    {void (void *)} \
+    - \
+    -
+add {base::operator char*} \
+    {char *(const base * const)} \
+    - \
+    -
+add {base::operator fluff*} \
+    {fluff *(const base * const)} \
+    - \
+    -
+add {base::operator fluff**} \
+    {fluff **(const base * const)} \
+    - \
+    -
+add {base::operator int} \
+    {int (const base * const)} \
+    - \
+    -
+
+# Templates
+add {tclass<char>::do_something} \
+    {void (tclass<char> * const)} \
+    - \
+    -
+add {tclass<int>::do_something} \
+    {void (tclass<int> * const)} \
+    - \
+    -
+add {tclass<long>::do_something} \
+    {void (tclass<long> * const)} \
+    - \
+    -
+add {tclass<short>::do_something} \
+    {void (tclass<short> * const)} \
+    - \
+    -
+add {tclass<base>::do_something} \
+    {void (tclass<base> * const)} \
+    - \
+    -
+add {flubber<int, int, int, int, int>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, int, short>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, int, long>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, int, char>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, short, int>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, short, short>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, short, long>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, short, char>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, long, int>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, long, short>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, long, long>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, long, char>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, char, int>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, char, short>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, char, long>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, int, char, char>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, short, int, int>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, short, int, short>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, short, int, long>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, short, int, char>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<int, int, short, short, int>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<short, int, short, int, short>} \
+    {void (void)} \
+    - \
+    flubber
+add {flubber<long, short, long, short, long>} \
+    {void (void)} \
+    - \
+    flubber
+add {tclass<base>::do_something} \
+    {void (tclass<base> * const)} \
+    - \
+    {tclass<T>::do_something}
+add {policy1::policy} \
+    [ctor "policy<int, operation_1<void*> >" "int"] \
+    {policy<int, operation_1<void*> >::policy} \
+    {policy<T, Policy>::policy}
+add {policy2::policy} \
+    [ctor "policy<int, operation_2<void*> >" int] \
+    {policy<int, operation_2<void*> >::policy} \
+    {policy<T, Policy>::policy}
+add {policy3::policy} \
+    [ctor "policy<int, operation_3<void*> >" "int"] \
+    {policy<int, operation_3<void*> >::policy} \
+    {policy<T, Policy>::policy}
+add {policy4::policy} \
+    [ctor "policy<int, operation_4<void*> >" "int"] \
+    {policy<int, operation_4<void*> >::policy} \
+    {policy<T, Policy>::policy}
+add {policy1::function} \
+    {void (void)} \
+    {operation_1<void*>::function} \
+    {operation_1<T>::function}
+add {policy2::function} \
+    {void (void)} \
+    {operation_2<void*>::function} \
+    {operation_2<T>::function}
+add {policy3::function} \
+    {void (void)} \
+    {operation_3<void*>::function} \
+    {operation_3<T>::function}
+add {policy4::function} \
+    {void (void)} \
+    {operation_4<void*>::function} \
+    {operation_4<T>::function}
+add {policyd<int, operation_1<int> >::policyd} \
+    [ctor "policyd<int, operation_1<int> >" "int"] \
+    - \
+    {policyd<T, Policy>::policyd}
+add {policyd1::policyd} \
+    [ctor "policyd<int, operation_1<int> >" "int"] \
+    {policyd<int, operation_1<int> >::policyd} \
+    {policyd<T, Policy>::policyd}
+add {policyd<int, operation_1<int> >::~policyd} \
+    [dtor "policyd<int, operation_1<int> >"] \
+    - \
+    {policyd<T, Policy>::~policyd}
+add {policyd1::~policyd} \
+    [dtor "policyd<int, operation_1<int> >"] \
+    {policyd<int, operation_1<int> >::~policyd} \
+    {policyd<T, Policy>::~policyd}
+add {policyd<long, operation_1<long> >::policyd} \
+    [ctor "policyd<long, operation_1<long> >" "long"] \
+    - \
+    {policyd<T, Policy>::policyd}
+add {policyd2::policyd} \
+    [ctor "policyd<long, operation_1<long> >" "long"] \
+    {policyd<long, operation_1<long> >::policyd} \
+    {policyd<T, Policy>::policyd}
+add {policyd<long, operation_1<long> >::~policyd} \
+    [dtor "policyd<long, operation_1<long> >"] \
+    - \
+    {policyd<T, Policy>::~policyd}
+add {policyd2::~policyd} \
+    [dtor "policyd<long, operation_1<long> >"] \
+    {policyd<long, operation_1<long> >::~policyd} \
+    {policyd<T, Policy>::~policyd}
+add {policyd<char, operation_1<char> >::policyd} \
+    [ctor "policyd<char, operation_1<char> >" "char"] \
+    - \
+    {policyd<T, Policy>::policyd}
+add {policyd3::policyd} \
+    [ctor "policyd<char, operation_1<char> >" "char"] \
+    {policyd<char, operation_1<char> >::policyd} \
+    {policyd<T, Policy>::policyd}
+add {policyd<char, operation_1<char> >::~policyd} \
+    [dtor "policyd<char, operation_1<char> >"] \
+    - \
+    {policyd<T, Policy>::~policyd}
+add {policyd3::~policyd} \
+    [dtor "policyd<char, operation_1<char> >"] \
+    {policyd<char, operation_1<char> >::~policyd} \
+    {policyd<T, Policy>::~policyd}
+add {policyd<base, operation_1<base> >::policyd} \
+    [ctor "policyd<base, operation_1<base> >" "base"] \
+    - \
+    {policyd<T, Policy>::policyd}
+add {policyd4::policyd} \
+    [ctor "policyd<base, operation_1<base> >" "base"] \
+    {policyd<base, operation_1<base> >::policyd} \
+    {policyd<T, Policy>::policyd}
+add {policyd<base, operation_1<base> >::~policyd} \
+    [dtor "policyd<base, operation_1<base> >"] \
+    - \
+    {policyd<T, Policy>::~policyd}
+add {policyd4::~policyd} \
+    [dtor "policyd<base, operation_1<base> >"] \
+    {policyd<base, operation_1<base> >::~policyd} \
+    {policyd<T, Policy>::~policyd}
+add {policyd<tclass<int>, operation_1<tclass<int> > >::policyd} \
+    [ctor "policyd<tclass<int>, operation_1<tclass<int> > >" "tclass<int>"] \
+    - \
+    {policyd<T, Policy>::policyd}
+add {policyd5::policyd} \
+    [ctor "policyd<tclass<int>, operation_1<tclass<int> > >" "tclass<int>"] \
+    {policyd<tclass<int>, operation_1<tclass<int> > >::policyd} \
+    {policyd<T, Policy>::policyd}
+add {policyd<tclass<int>, operation_1<tclass<int> > >::~policyd} \
+    [dtor "policyd<tclass<int>, operation_1<tclass<int> > >"] \
+    - \
+    {policyd<T, Policy>::~policyd}
+add {policyd5::~policyd} \
+    [dtor "policyd<tclass<int>, operation_1<tclass<int> > >"] \
+    {policyd<tclass<int>, operation_1<tclass<int> > >::~policyd} \
+    {policyd<T, Policy>::~policyd}
+add {policyd<int, operation_1<int> >::function} \
+    {void (void)} \
+    {operation_1<int>::function}\
+    {operation_1<T>::function}
+add {policyd1::function} \
+    {void (void)} \
+    {operation_1<int>::function} \
+    {operation_1<T>::function}
+add {policyd2::function} \
+    {void (void)} \
+    {operation_1<long>::function} \
+    {operation_1<T>::function}
+add {policyd<char, operation_1<char> >::function} \
+    {void (void)} \
+    {operation_1<char>::function} \
+    {operation_1<T>::function}
+add {policyd3::function} \
+    {void (void)} \
+    {operation_1<char>::function} \
+    {operation_1<T>::function}
+add {policyd<base, operation_1<base> >::function} \
+    {void (void)} \
+    {operation_1<base>::function} \
+    {operation_1<T>::function}
+add {policyd4::function} \
+    {void (void)} \
+    {operation_1<base>::function} \
+    {operation_1<T>::function}
+add {policyd<tclass<int>, operation_1<tclass<int> > >::function} \
+    {void (void)} \
+    {operation_1<tclass<int> >::function} \
+    {operation_1<T>::function}
+add {policyd5::function} \
+    {void (void)} \
+    {operation_1<tclass<int> >::function} \
+    {operation_1<T>::function}
+
+# Start the test
+if {$tracelevel} {
+    strace $tracelevel
+}
+
+if {[skip_cplus_tests]} { continue }
+
+#
+# test running programs
+#
+set prms_id 0
+set bug_id 0
+
+set testfile "cpexprs"
+set srcfile "${testfile}.cc"
+set binfile [file join $objdir $subdir $testfile]
+
+if  {[gdb_compile [file join $srcdir $subdir $srcfile] $binfile \
+	  executable {debug c++}] != "" } {
+    untested "$testfile.exp"
+    return -1
+}
+
+if {[get_compiler_info $binfile "c++"]} {
+    return -1
+}
+
+gdb_exit
+gdb_start
+gdb_reinitialize_dir [file join $srcdir $subdir]
+gdb_load $binfile
+
+if {![runto_main]} {
+    perror "couldn't run to breakpoint"
+    continue
+}
+
+# Set the listsize to one. This will help with testing "list".
+gdb_test "set listsize 1"
+
+# "print METHOD"
+foreach name [get_functions print] {
+    gdb_test "print $name" [get $name print] "print $name"
+}
+
+# "list METHOD"
+foreach name [get_functions list] {
+    gdb_test "list $name" [get $name list] "list $name"
+}
+
+# Running to breakpoint -- use any function we can "list"
+foreach name [get_functions list] {
+    # Skip "main", since test_breakpoint uses it
+    if {[string compare $name "main"] != 0} {
+	test_breakpoint $name
+    }
+}
+
+gdb_exit
+return 0
Index: testsuite/gdb.cp/cplusfuncs.cc
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/cplusfuncs.cc,v
retrieving revision 1.2
diff -u -p -r1.2 cplusfuncs.cc
--- testsuite/gdb.cp/cplusfuncs.cc	11 Nov 2009 16:45:16 -0000	1.2
+++ testsuite/gdb.cp/cplusfuncs.cc	28 Jan 2010 23:30:25 -0000
@@ -195,6 +195,12 @@ char *	dm_type_char_star (char * p)		{ r
 int	dm_type_foo_ref (foo & foo)		{ return foo.ifoo; }
 int *	dm_type_int_star (int * p)		{ return p; }
 long *	dm_type_long_star (long * p)		{ return p; }
+int	dm_type_short (short i)			{ return i; }
+int	dm_type_long (long i)			{ return i; }
 int	dm_type_unsigned_int (unsigned int i)	{ return i; }
+int	dm_type_unsigned_short (unsigned short i)	{ return i; }
+int	dm_type_unsigned_long (unsigned long i)	{ return i; }
 int	dm_type_void (void)			{ return 0; }
 void *	dm_type_void_star (void * p)		{ return p; }
+typedef int myint;
+int	dm_type_typedef (myint i)		{ return i; }
Index: testsuite/gdb.cp/cplusfuncs.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/cplusfuncs.exp,v
retrieving revision 1.11
diff -u -p -r1.11 cplusfuncs.exp
--- testsuite/gdb.cp/cplusfuncs.exp	1 Jan 2010 07:32:01 -0000	1.11
+++ testsuite/gdb.cp/cplusfuncs.exp	28 Jan 2010 23:30:25 -0000
@@ -66,9 +66,25 @@ set dm_type_unsigned_int	"unsigned"
 set dm_type_void		"void"
 set dm_type_void_star		"void*"
 
+# Some other vagaries of GDB's type printing machinery.  The integer types
+# may have unsigned before or after their length, and may have "int"
+# appended.  The char* conversion operator may have name "char*" even if
+# the type is "char *", because the name comes from the debug information
+# and the type from GDB.  Function types may not see through typedefs.
+
+set dm_type_short		"short"
+set dm_type_long		"long"
+set dm_type_unsigned_short	"unsigned short"
+set dm_type_unsigned_long	"unsigned long"
+set dm_operator_char_star	"char*"
+set dm_operator_char_star_quoted	"char\\*"
+set dm_type_typedef		0
+
 proc probe_demangler { } {
     global gdb_prompt
     global dm_operator_comma
+    global dm_operator_char_star
+    global dm_operator_char_star_quoted
     global dm_type_char_star
     global dm_type_char_star_quoted
     global dm_type_foo_ref
@@ -77,6 +93,11 @@ proc probe_demangler { } {
     global dm_type_unsigned_int
     global dm_type_void
     global dm_type_void_star
+    global dm_type_short
+    global dm_type_unsigned_short
+    global dm_type_long
+    global dm_type_unsigned_long
+    global dm_type_typedef
 
     send_gdb "print &foo::operator,(foo&)\n"
     gdb_expect {
@@ -97,6 +118,26 @@ proc probe_demangler { } {
 	}
     }
 
+    send_gdb "print &foo::operator char*($dm_type_void)\n"
+    gdb_expect {
+	-re ".*foo::operator char \\*\\(void\\).*\r\n$gdb_prompt $" {
+	    # v2 demangler or GDB type printer
+	    set dm_operator_char_star "char *"
+	    set dm_operator_char_star_quoted "char \\*"
+	    pass "detect dm_operator_char_star"
+	}
+	-re ".*foo::operator char\\*\\(\\).*\r\n$gdb_prompt $" {
+	    # v3 demangler
+	    pass "detect dm_operator_char_star"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_operator_char_star"
+	}
+	timeout {
+	    fail "detect dm_operator_char_star"
+	}
+    }
+
     send_gdb "print &dm_type_char_star\n"
     gdb_expect {
 	-re ".*dm_type_char_star\\(char \\*\\).*\r\n$gdb_prompt $" {
@@ -166,6 +207,11 @@ proc probe_demangler { } {
 	    # v3 demangler
 	    pass "detect dm_type_long_star"
 	}
+	-re ".*dm_type_long_star\\(long int \\*\\).*\r\n$gdb_prompt $" {
+	    # GCC v3 and GDB's type printer
+	    set dm_type_long_star "long int *"
+	    pass "detect dm_type_long_star"
+	}
 	-re ".*$gdb_prompt $" {
 	    fail "detect dm_type_long_star"
 	}
@@ -230,6 +276,101 @@ proc probe_demangler { } {
 	    fail "detect dm_type_void_star (timeout)"
 	}
     }
+
+    send_gdb "print &dm_type_short\n"
+    gdb_expect {
+	-re ".*dm_type_short\\(short\\).*\r\n$gdb_prompt $" {
+	    # v2 and v3 demanglers
+	    pass "detect dm_type_short"
+	}
+	-re ".*dm_type_short\\(short int\\).*\r\n$gdb_prompt $" {
+	    # GDB type printer
+	    set dm_type_short "short int"
+	    pass "detect dm_type_short"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_type_short"
+	}
+	timeout {
+	    fail "detect dm_type_short (timeout)"
+	}
+    }
+
+    send_gdb "print &dm_type_unsigned_short\n"
+    gdb_expect {
+	-re ".*dm_type_unsigned_short\\(unsigned short\\).*\r\n$gdb_prompt $" {
+	    # v2 and v3 demanglers
+	    pass "detect dm_type_unsigned_short"
+	}
+	-re ".*dm_type_unsigned_short\\(short unsigned int\\).*\r\n$gdb_prompt $" {
+	    # GDB type printer
+	    set dm_type_unsigned_short "short unsigned int"
+	    pass "detect dm_type_unsigned_short"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_type_unsigned_short"
+	}
+	timeout {
+	    fail "detect dm_type_unsigned_short (timeout)"
+	}
+    }
+
+    send_gdb "print &dm_type_long\n"
+    gdb_expect {
+	-re ".*dm_type_long\\(long\\).*\r\n$gdb_prompt $" {
+	    # v2 and v3 demanglers
+	    pass "detect dm_type_long"
+	}
+	-re ".*dm_type_long\\(long int\\).*\r\n$gdb_prompt $" {
+	    # GDB type printer
+	    set dm_type_long "long int"
+	    pass "detect dm_type_long"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_type_long"
+	}
+	timeout {
+	    fail "detect dm_type_long (timeout)"
+	}
+    }
+
+    send_gdb "print &dm_type_unsigned_long\n"
+    gdb_expect {
+	-re ".*dm_type_unsigned_long\\(unsigned long\\).*\r\n$gdb_prompt $" {
+	    # v2 and v3 demanglers
+	    pass "detect dm_type_unsigned_long"
+	}
+	-re ".*dm_type_unsigned_long\\(long unsigned int\\).*\r\n$gdb_prompt $" {
+	    # GDB type printer
+	    set dm_type_unsigned_long "long unsigned int"
+	    pass "detect dm_type_unsigned_long"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_type_unsigned_long"
+	}
+	timeout {
+	    fail "detect dm_type_unsigned_long (timeout)"
+	}
+    }
+
+    send_gdb "print &dm_type_typedef\n"
+    gdb_expect {
+	-re ".*dm_type_typedef\\(int\\).*\r\n$gdb_prompt $" {
+	    # v2 and v3 demanglers
+	    pass "detect dm_type_typedef"
+	}
+	-re ".*dm_type_typedef\\(myint\\).*\r\n$gdb_prompt $" {
+	    # GDB type printer
+	    set dm_type_typedef 1
+	    pass "detect dm_type_typedef"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_type_typedef"
+	}
+	timeout {
+	    fail "detect dm_type_typedef (timeout)"
+	}
+    }
 }
 
 #
@@ -351,8 +492,9 @@ proc print_addr { name } {
 
 proc test_lookup_operator_functions {} {
     global dm_operator_comma
+    global dm_operator_char_star
     global dm_type_char_star
-    global dm_type_char_star_quoted
+    global dm_operator_char_star_quoted
     global dm_type_foo_ref
     global dm_type_void
     global dm_type_void_star
@@ -410,8 +552,8 @@ proc test_lookup_operator_functions {} {
 
     info_func "operator int("	"int foo::operator int($dm_type_void);"
     info_func "operator()("	"void foo::operator()($dm_type_foo_ref);"
-    info_func "operator $dm_type_char_star_quoted\(" \
-				"char *foo::operator $dm_type_char_star\($dm_type_void);"
+    info_func "operator $dm_operator_char_star_quoted\(" \
+				"char *foo::operator $dm_operator_char_star\($dm_type_void);"
 
 }
 
@@ -426,6 +568,7 @@ proc test_paddr_operator_functions {} {
     global dm_type_unsigned_int
     global dm_type_void
     global dm_type_void_star
+    global dm_operator_char_star
 
     print_addr "foo::operator*($dm_type_foo_ref)"
     print_addr "foo::operator%($dm_type_foo_ref)"
@@ -479,7 +622,7 @@ proc test_paddr_operator_functions {} {
     }
 
     print_addr "foo::operator int($dm_type_void)"
-    print_addr "foo::operator $dm_type_char_star\($dm_type_void)"
+    print_addr "foo::operator $dm_operator_char_star\($dm_type_void)"
 }
 
 #
@@ -489,17 +632,21 @@ proc test_paddr_operator_functions {} {
 proc test_paddr_overloaded_functions {} {
     global dm_type_unsigned_int
     global dm_type_void
+    global dm_type_short
+    global dm_type_unsigned_short
+    global dm_type_long
+    global dm_type_unsigned_long
 
     print_addr "overload1arg($dm_type_void)"
     print_addr "overload1arg(char)"
     print_addr "overload1arg(signed char)"
     print_addr "overload1arg(unsigned char)"
-    print_addr "overload1arg(short)"
-    print_addr "overload1arg(unsigned short)"
+    print_addr "overload1arg($dm_type_short)"
+    print_addr "overload1arg($dm_type_unsigned_short)"
     print_addr "overload1arg(int)"
     print_addr "overload1arg($dm_type_unsigned_int)"
-    print_addr "overload1arg(long)"
-    print_addr "overload1arg(unsigned long)"
+    print_addr "overload1arg($dm_type_long)"
+    print_addr "overload1arg($dm_type_unsigned_long)"
     print_addr "overload1arg(float)"
     print_addr "overload1arg(double)"
 
@@ -522,17 +669,31 @@ proc test_paddr_hairy_functions {} {
     global dm_type_char_star
     global dm_type_int_star
     global dm_type_long_star
+    global dm_type_typedef
 
     print_addr_2 "hairyfunc1" "hairyfunc1(int)"
-    print_addr_2 "hairyfunc2" "hairyfunc2(int (*)($dm_type_char_star))"
-    print_addr_2 "hairyfunc3" "hairyfunc3(int (*)(short (*)($dm_type_long_star)))"
-    print_addr_2 "hairyfunc4" "hairyfunc4(int (*)(short (*)($dm_type_char_star)))"
-
-    # gdb-gnats bug gdb/19:
-    # "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7"
-    print_addr_2_kfail "hairyfunc5" "hairyfunc5(int (*(*)($dm_type_char_star))(long))" "hairyfunc5(int (*)(long) (*)(char*))" "gdb/19"
-    print_addr_2_kfail "hairyfunc6" "hairyfunc6(int (*(*)($dm_type_int_star))(long))" "hairyfunc6(int (*)(long) (*)(int*))" "gdb/19"
-    print_addr_2_kfail "hairyfunc7" "hairyfunc7(int (*(*)(int (*)($dm_type_char_star)))(long))" "hairyfunc7(int (*)(long) (*)(int (*)(char*)))" "gdb/19"
+
+    if {$dm_type_typedef == 0} {
+	print_addr_2 "hairyfunc2" "hairyfunc2(int (*)($dm_type_char_star))"
+	print_addr_2 "hairyfunc3" "hairyfunc3(int (*)(short (*)($dm_type_long_star)))"
+	print_addr_2 "hairyfunc4" "hairyfunc4(int (*)(short (*)($dm_type_char_star)))"
+
+	# gdb-gnats bug gdb/19:
+	# "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7"
+	print_addr_2_kfail "hairyfunc5" "hairyfunc5(int (*(*)($dm_type_char_star))(long))" "hairyfunc5(int (*)(long) (*)(char*))" "gdb/19"
+	print_addr_2_kfail "hairyfunc6" "hairyfunc6(int (*(*)($dm_type_int_star))(long))" "hairyfunc6(int (*)(long) (*)(int*))" "gdb/19"
+	print_addr_2_kfail "hairyfunc7" "hairyfunc7(int (*(*)(int (*)($dm_type_char_star)))(long))" "hairyfunc7(int (*)(long) (*)(int (*)(char*)))" "gdb/19"
+    } else {
+	print_addr_2 "hairyfunc2" "hairyfunc2(PFPc_i)"
+	print_addr_2 "hairyfunc3" "hairyfunc3(PFPFPl_s_i)"
+	print_addr_2 "hairyfunc4" "hairyfunc4(PFPFPc_s_i)"
+
+	# gdb-gnats bug gdb/19:
+	# "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7"
+	print_addr_2 "hairyfunc5" "hairyfunc5(PFPc_PFl_i)"
+	print_addr_2 "hairyfunc6" "hairyfunc6(PFPi_PFl_i)"
+	print_addr_2 "hairyfunc7" "hairyfunc7(PFPFPc_i_PFl_i)"
+    }
 }
 
 proc do_tests {} {
Index: testsuite/gdb.cp/exception.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/exception.exp,v
retrieving revision 1.16
diff -u -p -r1.16 exception.exp
--- testsuite/gdb.cp/exception.exp	1 Jan 2010 07:32:01 -0000	1.16
+++ testsuite/gdb.cp/exception.exp	28 Jan 2010 23:30:26 -0000
@@ -146,7 +146,9 @@ gdb_test_multiple "continue" $name {
 
 set name "backtrace after first throw"
 gdb_test_multiple "backtrace" $name {
-    -re ".*#\[0-9\]+${ws}($hex in |)__cxa_throw.*#\[0-9\]+${ws}$hex in foo \\(i=20\\) at .*${srcfile}:\[0-9\]+\r\n#\[0-9\]+${ws}$hex in main \\(.*\\) at .*${srcfile}:\[0-9\]+\r\n$gdb_prompt $" {
+    -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_throw\[\[:>:\]\].*#\[0-9\]+${ws}$hex in foo \\(i=20\\) at .*${srcfile}:\[0-9\]+\r\n#\[0-9\]+${ws}$hex in main \\(.*\\) at .*${srcfile}:\[0-9\]+\r\n$gdb_prompt $" {
+	# Either __cxxabiv1::__cxa_throw or __cxa_throw can be printed
+	# depending on debug info presence.
 	pass $name
     }
 }
@@ -168,7 +170,7 @@ gdb_test_multiple "continue" $name {
 
 set name "backtrace after first catch"
 gdb_test_multiple "backtrace" $name {
-    -re ".*#\[0-9\]+${ws}($hex in |)__cxa_begin_catch.*#\[0-9\]+${ws}$hex in main \\(.*\\) at .*$srcfile:\[0-9\]+\r\n$gdb_prompt $" {
+    -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_begin_catch\[\[:>:\]\].*#\[0-9\]+${ws}$hex in main \\(.*\\) at .*$srcfile:\[0-9\]+\r\n$gdb_prompt $" {
 	pass $name
     }
 }
@@ -190,7 +192,7 @@ gdb_test_multiple "continue" $name {
 
 set name "backtrace after second throw"
 gdb_test_multiple "backtrace" $name {
-    -re ".*#\[0-9\]+${ws}($hex in |)__cxa_throw.*#\[0-9\]+${ws}$hex in foo \\(i=20\\) at .*${srcfile}:\[0-9\]+\r\n#\[0-9\]+${ws}$hex in main \\(.*\\) at .*${srcfile}:\[0-9\]+\r\n$gdb_prompt $" {
+    -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_throw\[\[:>:\]\].*#\[0-9\]+${ws}$hex in foo \\(i=20\\) at .*${srcfile}:\[0-9\]+\r\n#\[0-9\]+${ws}$hex in main \\(.*\\) at .*${srcfile}:\[0-9\]+\r\n$gdb_prompt $" {
 	pass $name
     }
 }
@@ -212,7 +214,7 @@ gdb_test_multiple "continue" $name {
 
 set name "backtrace after second catch"
 gdb_test_multiple "backtrace" $name {
-    -re ".*#\[0-9\]+${ws}($hex in |)__cxa_begin_catch.*#\[0-9\]+${ws}$hex in main \\(.*\\) at .*$srcfile:\[0-9\]+\r\n$gdb_prompt $" {
+    -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_begin_catch\[\[:>:\]\].*#\[0-9\]+${ws}$hex in main \\(.*\\) at .*$srcfile:\[0-9\]+\r\n$gdb_prompt $" {
 	pass $name
     }
 }
Index: testsuite/gdb.cp/expand-sals.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/expand-sals.exp,v
retrieving revision 1.3
diff -u -p -r1.3 expand-sals.exp
--- testsuite/gdb.cp/expand-sals.exp	1 Jan 2010 07:32:01 -0000	1.3
+++ testsuite/gdb.cp/expand-sals.exp	28 Jan 2010 23:30:26 -0000
@@ -46,7 +46,7 @@ gdb_continue_to_breakpoint "caller" ".*c
 
 # Test GDB caught this return call and not the next one through B::B()
 gdb_test "bt" \
-	 "#0 \[^\r\n\]* A \[^\r\n\]*\r\n#1 \[^\r\n\]* main \[^\r\n\]*" \
+	 "#0 \[^\r\n\]* (A::)?A \[^\r\n\]*\r\n#1 \[^\r\n\]* main \[^\r\n\]*" \
 	 "bt from A"
 
 gdb_continue_to_breakpoint "next caller func" ".*func-line.*"
Index: testsuite/gdb.cp/member-ptr.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/member-ptr.exp,v
retrieving revision 1.11
diff -u -p -r1.11 member-ptr.exp
--- testsuite/gdb.cp/member-ptr.exp	1 Jan 2010 07:32:01 -0000	1.11
+++ testsuite/gdb.cp/member-ptr.exp	28 Jan 2010 23:30:26 -0000
@@ -420,7 +420,7 @@ gdb_test_multiple "ptype pmf" $name {
 
 set name "print pmf"
 gdb_test_multiple "print pmf" $name {
-    -re "$vhn = $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
+    -re "$vhn = \\(int \\(A::\\*\\)\\(A \\*, int\\)\\) $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
 	pass $name
     }
     -re "$vhn = .*not supported with HP aCC.*\r\n$gdb_prompt $" {
@@ -608,6 +608,8 @@ gdb_test_multiple "print (a.*pmf)(3)" $n
     }
 }
 
+gdb_test "ptype a.*pmf" "type = int \\(A \\*, int\\)"
+
 # Print out a pointer to data member which requires looking into
 # a base class.
 gdb_test "print diamond_pmi" "$vhn = &Base::x"
@@ -658,5 +660,5 @@ gdb_test "print null_pmi = &A::j" "$vhn 
 gdb_test "print null_pmi = 0" "$vhn = NULL"
 
 gdb_test "print null_pmf" "$vhn = NULL"
-gdb_test "print null_pmf = &A::foo" "$vhn = $hex <A::foo ?\\(int\\)>"
+gdb_test "print null_pmf = &A::foo" "$vhn = \\(int \\(A::\\*\\)\\(A \\*, int\\)\\) $hex <A::foo ?\\(int\\)>"
 gdb_test "print null_pmf = 0" "$vhn = NULL"
Index: testsuite/gdb.cp/overload.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/overload.exp,v
retrieving revision 1.13
diff -u -p -r1.13 overload.exp
--- testsuite/gdb.cp/overload.exp	1 Jan 2010 07:32:01 -0000	1.13
+++ testsuite/gdb.cp/overload.exp	28 Jan 2010 23:30:26 -0000
@@ -74,12 +74,12 @@ set re_methods	"${re_methods}${ws}int ov
 set re_methods	"${re_methods}${ws}int overload1arg\\(char\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(signed char\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(unsigned char\\);"
-set re_methods	"${re_methods}${ws}int overload1arg\\(short\\);"
-set re_methods	"${re_methods}${ws}int overload1arg\\(unsigned short\\);"
+set re_methods	"${re_methods}${ws}int overload1arg\\(short( int)?\\);"
+set re_methods	"${re_methods}${ws}int overload1arg\\((unsigned short|short unsigned)( int)?\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(int\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(unsigned int\\);"
-set re_methods	"${re_methods}${ws}int overload1arg\\(long\\);"
-set re_methods	"${re_methods}${ws}int overload1arg\\(unsigned long\\);"
+set re_methods	"${re_methods}${ws}int overload1arg\\(long( int)?\\);"
+set re_methods	"${re_methods}${ws}int overload1arg\\((unsigned long|long unsigned)( int)?\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(float\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(double\\);"
 set re_methods	"${re_methods}${ws}int overloadfnarg\\((void|)\\);"
Index: testsuite/gdb.cp/ovldbreak.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/ovldbreak.exp,v
retrieving revision 1.12
diff -u -p -r1.12 ovldbreak.exp
--- testsuite/gdb.cp/ovldbreak.exp	1 Jan 2010 07:32:01 -0000	1.12
+++ testsuite/gdb.cp/ovldbreak.exp	28 Jan 2010 23:30:26 -0000
@@ -23,7 +23,8 @@
 # overloaded member functions
 #
 
-
+global timeout
+set timeout 15
 if $tracelevel then {
         strace $tracelevel
         }
@@ -127,10 +128,24 @@ proc set_bp_overloaded {name expectedmen
 }
 
 # This is the expected menu for overload1arg.
-# Note the arg type variations on lines 6 and 13.
+# Note the arg type variations for void and integer types.
 # This accommodates different versions of g++.
 
-set menu_overload1arg "\\\[0\\\] cancel\r\n\\\[1\\\] all\r\n\\\[2\\\] foo::overload1arg\\(double\\) at.*$srcfile:121\r\n\\\[3\\\] foo::overload1arg\\(float\\) at.*$srcfile:120\r\n\\\[4\\\] foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r\n\\\[5\\\] foo::overload1arg\\(long\\) at.*$srcfile:118\r\n\\\[6\\\] foo::overload1arg\\((unsigned int|unsigned)\\) at.*$srcfile:117\r\n\\\[7\\\] foo::overload1arg\\(int\\) at.*$srcfile:116\r\n\\\[8\\\] foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r\n\\\[9\\\] foo::overload1arg\\(short\\) at.*$srcfile:114\r\n\\\[10\\\] foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r\n\\\[11\\\] foo::overload1arg\\(signed char\\) at.*$srcfile:112\r\n\\\[12\\\] foo::overload1arg\\(char\\) at.*$srcfile:111\r\n\\\[13\\\] foo::overload1arg\\((void|)\\) at.*$srcfile:110\r\n> $"
+set    menu_overload1arg "\\\[0\\\] cancel\r\n"
+append menu_overload1arg "\\\[1\\\] all\r\n"
+append menu_overload1arg "\\\[2\\\] foo::overload1arg\\(double\\) at.*$srcfile:121\r\n"
+append menu_overload1arg "\\\[3\\\] foo::overload1arg\\(float\\) at.*$srcfile:120\r\n"
+append menu_overload1arg "\\\[4\\\] foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r\n"
+append menu_overload1arg "\\\[5\\\] foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r\n"
+append menu_overload1arg "\\\[6\\\] foo::overload1arg\\((unsigned int|unsigned)\\) at.*$srcfile:117\r\n"
+append menu_overload1arg "\\\[7\\\] foo::overload1arg\\(int\\) at.*$srcfile:116\r\n"
+append menu_overload1arg "\\\[8\\\] foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r\n"
+append menu_overload1arg "\\\[9\\\] foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r\n"
+append menu_overload1arg "\\\[10\\\] foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r\n"
+append menu_overload1arg "\\\[11\\\] foo::overload1arg\\(signed char\\) at.*$srcfile:112\r\n"
+append menu_overload1arg "\\\[12\\\] foo::overload1arg\\(char\\) at.*$srcfile:111\r\n"
+append menu_overload1arg "\\\[13\\\] foo::overload1arg\\((void|)\\) at.*$srcfile:110\r\n"
+append menu_overload1arg "> $"
 
 # Set multiple-symbols to "ask", to allow us to test the use
 # of the multiple-choice menu when breaking on an overloaded method.
@@ -157,17 +172,17 @@ set_bp_overloaded "foo::overload1arg" "$
 
 gdb_test "info break" \
     "Num     Type\[\t \]+Disp Enb Address\[\t \]+What.*
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in main at.*$srcfile:49\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in main(\\((|void)\\))? at.*$srcfile:49\r
 \[\t \]+breakpoint already hit 1 time\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((void|)\\) at.*$srcfile:110" \
@@ -215,17 +230,17 @@ gdb_expect {
 
 gdb_test "info break" \
     "Num     Type\[\t \]+Disp Enb Address\[\t \]+What.*
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in main at.*$srcfile:49\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in main(\\((|void)\\))? at.*$srcfile:49\r
 \[\t \]+breakpoint already hit 1 time\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((void|)\\) at.*$srcfile:110" \
@@ -296,12 +311,12 @@ gdb_test "info break" \
     "Num     Type\[\t \]+Disp Enb Address\[\t \]+What.*
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
Index: testsuite/gdb.java/jmain.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.java/jmain.exp,v
retrieving revision 1.11
diff -u -p -r1.11 jmain.exp
--- testsuite/gdb.java/jmain.exp	1 Jan 2010 07:32:03 -0000	1.11
+++ testsuite/gdb.java/jmain.exp	28 Jan 2010 23:30:26 -0000
@@ -65,7 +65,7 @@ gdb_test "break jmain.main" "${bpmain}"
 
 # Check that a fully qualified "main" works.
 gdb_load "${binfile}"
-set cmd "break \'${testfile}.main(java.lang.String\[\])\'"
+set cmd "break ${testfile}.main(java.lang.String\[\])"
 set msg $cmd
 gdb_test_multiple $cmd $msg {
     -re "${bpmain}\r\n$gdb_prompt $" {
@@ -79,7 +79,7 @@ gdb_test_multiple $cmd $msg {
 	gdb_test "n" "" ""
 
 	# Check again with a method signature at the end.
-	set cmd "break \'${testfile}.main(java.lang.String\[\])void\'"
+	set cmd "break ${testfile}.main(java.lang.String\[\])void"
 	set msg $cmd
 	gdb_test_multiple $cmd $msg {
 	    -re "${bpmain}\r\n$gdb_prompt $" {
Index: testsuite/gdb.java/jmisc.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.java/jmisc.exp,v
retrieving revision 1.14
diff -u -p -r1.14 jmisc.exp
--- testsuite/gdb.java/jmisc.exp	1 Jan 2010 07:32:03 -0000	1.14
+++ testsuite/gdb.java/jmisc.exp	28 Jan 2010 23:30:26 -0000
@@ -71,8 +71,8 @@ if ![set_lang_java] then {
     # signature.
     runto_main
     set function "${testfile}.main(java.lang.String\[\])"
-    gdb_breakpoint "\'$function\'" { allow-pending }
-    gdb_breakpoint "\'${function}void\'" { allow-pending }
+    gdb_breakpoint "$function" { allow-pending }
+    gdb_breakpoint "${function}void" { allow-pending }
     gdb_continue_to_breakpoint $function
 
     send_gdb "ptype jmisc\n"   
Index: testsuite/gdb.java/jprint.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.java/jprint.exp,v
retrieving revision 1.10
diff -u -p -r1.10 jprint.exp
--- testsuite/gdb.java/jprint.exp	1 Jan 2010 07:32:03 -0000	1.10
+++ testsuite/gdb.java/jprint.exp	28 Jan 2010 23:30:26 -0000
@@ -70,8 +70,8 @@ if ![set_lang_java] then {
     # signature.
     runto_main
     set function "${testfile}.main(java.lang.String\[\])"
-    gdb_breakpoint "\'$function\'" { allow-pending }
-    gdb_breakpoint "\'${function}void\'" { allow-pending }
+    gdb_breakpoint "$function" { allow-pending }
+    gdb_breakpoint "${function}void" { allow-pending }
     gdb_continue_to_breakpoint $function
 
     gdb_test "p jvclass.addprint(4,5,6)" "sum is 15\r\n.*" "unambiguous static call"

[-- Attachment #5: dwarf2_physname-tests-2.patch --]
[-- Type: text/plain, Size: 30259 bytes --]

Index: testsuite/gdb.cp/cp-relocate.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/cp-relocate.exp,v
retrieving revision 1.7
diff -u -p -r1.7 cp-relocate.exp
--- testsuite/gdb.cp/cp-relocate.exp	1 Jan 2010 07:32:01 -0000	1.7
+++ testsuite/gdb.cp/cp-relocate.exp	28 Jan 2010 23:27:11 -0000
@@ -30,7 +30,7 @@ proc get_func_address { func } {
     global gdb_prompt hex
 
     set rfunc [string_to_regexp $func]
-    gdb_test_multiple "print '${func}'" "get address of ${func}" {
+    gdb_test_multiple "print ${func}" "get address of ${func}" {
 	-re "\\\$\[0-9\]+ = \\{.*\\} (0|($hex) <${rfunc}>)\[\r\n\]+${gdb_prompt} $" {
 	    # $1 = {int ()} 0x24 <function_bar>
 	    # But if the function is at zero, the name may be omitted.
@@ -130,7 +130,7 @@ gdb_test "add-symbol-file ${binfile} 0 -
 	"y"
 
 # Make sure the function addresses were updated.
-gdb_test "break *'$func1_name'" \
+gdb_test "break *$func1_name" \
     "Breakpoint $decimal at 0x1....: file .*"
-gdb_test "break *'$func2_name'" \
+gdb_test "break *$func2_name" \
     "Breakpoint $decimal at 0x2....: file .*"
Index: testsuite/gdb.cp/cplusfuncs.cc
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/cplusfuncs.cc,v
retrieving revision 1.2
diff -u -p -r1.2 cplusfuncs.cc
--- testsuite/gdb.cp/cplusfuncs.cc	11 Nov 2009 16:45:16 -0000	1.2
+++ testsuite/gdb.cp/cplusfuncs.cc	28 Jan 2010 23:27:14 -0000
@@ -195,6 +195,12 @@ char *	dm_type_char_star (char * p)		{ r
 int	dm_type_foo_ref (foo & foo)		{ return foo.ifoo; }
 int *	dm_type_int_star (int * p)		{ return p; }
 long *	dm_type_long_star (long * p)		{ return p; }
+int	dm_type_short (short i)			{ return i; }
+int	dm_type_long (long i)			{ return i; }
 int	dm_type_unsigned_int (unsigned int i)	{ return i; }
+int	dm_type_unsigned_short (unsigned short i)	{ return i; }
+int	dm_type_unsigned_long (unsigned long i)	{ return i; }
 int	dm_type_void (void)			{ return 0; }
 void *	dm_type_void_star (void * p)		{ return p; }
+typedef int myint;
+int	dm_type_typedef (myint i)		{ return i; }
Index: testsuite/gdb.cp/cplusfuncs.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/cplusfuncs.exp,v
retrieving revision 1.11
diff -u -p -r1.11 cplusfuncs.exp
--- testsuite/gdb.cp/cplusfuncs.exp	1 Jan 2010 07:32:01 -0000	1.11
+++ testsuite/gdb.cp/cplusfuncs.exp	28 Jan 2010 23:27:17 -0000
@@ -66,9 +66,25 @@ set dm_type_unsigned_int	"unsigned"
 set dm_type_void		"void"
 set dm_type_void_star		"void*"
 
+# Some other vagaries of GDB's type printing machinery.  The integer types
+# may have unsigned before or after their length, and may have "int"
+# appended.  The char* conversion operator may have name "char*" even if
+# the type is "char *", because the name comes from the debug information
+# and the type from GDB.  Function types may not see through typedefs.
+
+set dm_type_short		"short"
+set dm_type_long		"long"
+set dm_type_unsigned_short	"unsigned short"
+set dm_type_unsigned_long	"unsigned long"
+set dm_operator_char_star	"char*"
+set dm_operator_char_star_quoted	"char\\*"
+set dm_type_typedef		0
+
 proc probe_demangler { } {
     global gdb_prompt
     global dm_operator_comma
+    global dm_operator_char_star
+    global dm_operator_char_star_quoted
     global dm_type_char_star
     global dm_type_char_star_quoted
     global dm_type_foo_ref
@@ -77,6 +93,11 @@ proc probe_demangler { } {
     global dm_type_unsigned_int
     global dm_type_void
     global dm_type_void_star
+    global dm_type_short
+    global dm_type_unsigned_short
+    global dm_type_long
+    global dm_type_unsigned_long
+    global dm_type_typedef
 
     send_gdb "print &foo::operator,(foo&)\n"
     gdb_expect {
@@ -97,6 +118,26 @@ proc probe_demangler { } {
 	}
     }
 
+    send_gdb "print &foo::operator char*($dm_type_void)\n"
+    gdb_expect {
+	-re ".*foo::operator char \\*\\(void\\).*\r\n$gdb_prompt $" {
+	    # v2 demangler or GDB type printer
+	    set dm_operator_char_star "char *"
+	    set dm_operator_char_star_quoted "char \\*"
+	    pass "detect dm_operator_char_star"
+	}
+	-re ".*foo::operator char\\*\\(\\).*\r\n$gdb_prompt $" {
+	    # v3 demangler
+	    pass "detect dm_operator_char_star"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_operator_char_star"
+	}
+	timeout {
+	    fail "detect dm_operator_char_star"
+	}
+    }
+
     send_gdb "print &dm_type_char_star\n"
     gdb_expect {
 	-re ".*dm_type_char_star\\(char \\*\\).*\r\n$gdb_prompt $" {
@@ -166,6 +207,11 @@ proc probe_demangler { } {
 	    # v3 demangler
 	    pass "detect dm_type_long_star"
 	}
+	-re ".*dm_type_long_star\\(long int \\*\\).*\r\n$gdb_prompt $" {
+	    # GCC v3 and GDB's type printer
+	    set dm_type_long_star "long int *"
+	    pass "detect dm_type_long_star"
+	}
 	-re ".*$gdb_prompt $" {
 	    fail "detect dm_type_long_star"
 	}
@@ -230,6 +276,101 @@ proc probe_demangler { } {
 	    fail "detect dm_type_void_star (timeout)"
 	}
     }
+
+    send_gdb "print &dm_type_short\n"
+    gdb_expect {
+	-re ".*dm_type_short\\(short\\).*\r\n$gdb_prompt $" {
+	    # v2 and v3 demanglers
+	    pass "detect dm_type_short"
+	}
+	-re ".*dm_type_short\\(short int\\).*\r\n$gdb_prompt $" {
+	    # GDB type printer
+	    set dm_type_short "short int"
+	    pass "detect dm_type_short"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_type_short"
+	}
+	timeout {
+	    fail "detect dm_type_short (timeout)"
+	}
+    }
+
+    send_gdb "print &dm_type_unsigned_short\n"
+    gdb_expect {
+	-re ".*dm_type_unsigned_short\\(unsigned short\\).*\r\n$gdb_prompt $" {
+	    # v2 and v3 demanglers
+	    pass "detect dm_type_unsigned_short"
+	}
+	-re ".*dm_type_unsigned_short\\(short unsigned int\\).*\r\n$gdb_prompt $" {
+	    # GDB type printer
+	    set dm_type_unsigned_short "short unsigned int"
+	    pass "detect dm_type_unsigned_short"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_type_unsigned_short"
+	}
+	timeout {
+	    fail "detect dm_type_unsigned_short (timeout)"
+	}
+    }
+
+    send_gdb "print &dm_type_long\n"
+    gdb_expect {
+	-re ".*dm_type_long\\(long\\).*\r\n$gdb_prompt $" {
+	    # v2 and v3 demanglers
+	    pass "detect dm_type_long"
+	}
+	-re ".*dm_type_long\\(long int\\).*\r\n$gdb_prompt $" {
+	    # GDB type printer
+	    set dm_type_long "long int"
+	    pass "detect dm_type_long"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_type_long"
+	}
+	timeout {
+	    fail "detect dm_type_long (timeout)"
+	}
+    }
+
+    send_gdb "print &dm_type_unsigned_long\n"
+    gdb_expect {
+	-re ".*dm_type_unsigned_long\\(unsigned long\\).*\r\n$gdb_prompt $" {
+	    # v2 and v3 demanglers
+	    pass "detect dm_type_unsigned_long"
+	}
+	-re ".*dm_type_unsigned_long\\(long unsigned int\\).*\r\n$gdb_prompt $" {
+	    # GDB type printer
+	    set dm_type_unsigned_long "long unsigned int"
+	    pass "detect dm_type_unsigned_long"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_type_unsigned_long"
+	}
+	timeout {
+	    fail "detect dm_type_unsigned_long (timeout)"
+	}
+    }
+
+    send_gdb "print &dm_type_typedef\n"
+    gdb_expect {
+	-re ".*dm_type_typedef\\(int\\).*\r\n$gdb_prompt $" {
+	    # v2 and v3 demanglers
+	    pass "detect dm_type_typedef"
+	}
+	-re ".*dm_type_typedef\\(myint\\).*\r\n$gdb_prompt $" {
+	    # GDB type printer
+	    set dm_type_typedef 1
+	    pass "detect dm_type_typedef"
+	}
+	-re ".*$gdb_prompt $" {
+	    fail "detect dm_type_typedef"
+	}
+	timeout {
+	    fail "detect dm_type_typedef (timeout)"
+	}
+    }
 }
 
 #
@@ -351,8 +492,9 @@ proc print_addr { name } {
 
 proc test_lookup_operator_functions {} {
     global dm_operator_comma
+    global dm_operator_char_star
     global dm_type_char_star
-    global dm_type_char_star_quoted
+    global dm_operator_char_star_quoted
     global dm_type_foo_ref
     global dm_type_void
     global dm_type_void_star
@@ -410,8 +552,8 @@ proc test_lookup_operator_functions {} {
 
     info_func "operator int("	"int foo::operator int($dm_type_void);"
     info_func "operator()("	"void foo::operator()($dm_type_foo_ref);"
-    info_func "operator $dm_type_char_star_quoted\(" \
-				"char *foo::operator $dm_type_char_star\($dm_type_void);"
+    info_func "operator $dm_operator_char_star_quoted\(" \
+				"char *foo::operator $dm_operator_char_star\($dm_type_void);"
 
 }
 
@@ -426,6 +568,7 @@ proc test_paddr_operator_functions {} {
     global dm_type_unsigned_int
     global dm_type_void
     global dm_type_void_star
+    global dm_operator_char_star
 
     print_addr "foo::operator*($dm_type_foo_ref)"
     print_addr "foo::operator%($dm_type_foo_ref)"
@@ -479,7 +622,7 @@ proc test_paddr_operator_functions {} {
     }
 
     print_addr "foo::operator int($dm_type_void)"
-    print_addr "foo::operator $dm_type_char_star\($dm_type_void)"
+    print_addr "foo::operator $dm_operator_char_star\($dm_type_void)"
 }
 
 #
@@ -489,17 +632,21 @@ proc test_paddr_operator_functions {} {
 proc test_paddr_overloaded_functions {} {
     global dm_type_unsigned_int
     global dm_type_void
+    global dm_type_short
+    global dm_type_unsigned_short
+    global dm_type_long
+    global dm_type_unsigned_long
 
     print_addr "overload1arg($dm_type_void)"
     print_addr "overload1arg(char)"
     print_addr "overload1arg(signed char)"
     print_addr "overload1arg(unsigned char)"
-    print_addr "overload1arg(short)"
-    print_addr "overload1arg(unsigned short)"
+    print_addr "overload1arg($dm_type_short)"
+    print_addr "overload1arg($dm_type_unsigned_short)"
     print_addr "overload1arg(int)"
     print_addr "overload1arg($dm_type_unsigned_int)"
-    print_addr "overload1arg(long)"
-    print_addr "overload1arg(unsigned long)"
+    print_addr "overload1arg($dm_type_long)"
+    print_addr "overload1arg($dm_type_unsigned_long)"
     print_addr "overload1arg(float)"
     print_addr "overload1arg(double)"
 
@@ -522,17 +669,31 @@ proc test_paddr_hairy_functions {} {
     global dm_type_char_star
     global dm_type_int_star
     global dm_type_long_star
+    global dm_type_typedef
 
     print_addr_2 "hairyfunc1" "hairyfunc1(int)"
-    print_addr_2 "hairyfunc2" "hairyfunc2(int (*)($dm_type_char_star))"
-    print_addr_2 "hairyfunc3" "hairyfunc3(int (*)(short (*)($dm_type_long_star)))"
-    print_addr_2 "hairyfunc4" "hairyfunc4(int (*)(short (*)($dm_type_char_star)))"
-
-    # gdb-gnats bug gdb/19:
-    # "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7"
-    print_addr_2_kfail "hairyfunc5" "hairyfunc5(int (*(*)($dm_type_char_star))(long))" "hairyfunc5(int (*)(long) (*)(char*))" "gdb/19"
-    print_addr_2_kfail "hairyfunc6" "hairyfunc6(int (*(*)($dm_type_int_star))(long))" "hairyfunc6(int (*)(long) (*)(int*))" "gdb/19"
-    print_addr_2_kfail "hairyfunc7" "hairyfunc7(int (*(*)(int (*)($dm_type_char_star)))(long))" "hairyfunc7(int (*)(long) (*)(int (*)(char*)))" "gdb/19"
+
+    if {$dm_type_typedef == 0} {
+	print_addr_2 "hairyfunc2" "hairyfunc2(int (*)($dm_type_char_star))"
+	print_addr_2 "hairyfunc3" "hairyfunc3(int (*)(short (*)($dm_type_long_star)))"
+	print_addr_2 "hairyfunc4" "hairyfunc4(int (*)(short (*)($dm_type_char_star)))"
+
+	# gdb-gnats bug gdb/19:
+	# "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7"
+	print_addr_2_kfail "hairyfunc5" "hairyfunc5(int (*(*)($dm_type_char_star))(long))" "hairyfunc5(int (*)(long) (*)(char*))" "gdb/19"
+	print_addr_2_kfail "hairyfunc6" "hairyfunc6(int (*(*)($dm_type_int_star))(long))" "hairyfunc6(int (*)(long) (*)(int*))" "gdb/19"
+	print_addr_2_kfail "hairyfunc7" "hairyfunc7(int (*(*)(int (*)($dm_type_char_star)))(long))" "hairyfunc7(int (*)(long) (*)(int (*)(char*)))" "gdb/19"
+    } else {
+	print_addr_2 "hairyfunc2" "hairyfunc2(PFPc_i)"
+	print_addr_2 "hairyfunc3" "hairyfunc3(PFPFPl_s_i)"
+	print_addr_2 "hairyfunc4" "hairyfunc4(PFPFPc_s_i)"
+
+	# gdb-gnats bug gdb/19:
+	# "gdb v3 demangler fails on hairyfunc5 hairyfunc6 hairyfunc7"
+	print_addr_2 "hairyfunc5" "hairyfunc5(PFPc_PFl_i)"
+	print_addr_2 "hairyfunc6" "hairyfunc6(PFPi_PFl_i)"
+	print_addr_2 "hairyfunc7" "hairyfunc7(PFPFPc_i_PFl_i)"
+    }
 }
 
 proc do_tests {} {
Index: testsuite/gdb.cp/expand-sals.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/expand-sals.exp,v
retrieving revision 1.3
diff -u -p -r1.3 expand-sals.exp
--- testsuite/gdb.cp/expand-sals.exp	1 Jan 2010 07:32:01 -0000	1.3
+++ testsuite/gdb.cp/expand-sals.exp	28 Jan 2010 23:27:20 -0000
@@ -46,7 +46,7 @@ gdb_continue_to_breakpoint "caller" ".*c
 
 # Test GDB caught this return call and not the next one through B::B()
 gdb_test "bt" \
-	 "#0 \[^\r\n\]* A \[^\r\n\]*\r\n#1 \[^\r\n\]* main \[^\r\n\]*" \
+	 "#0 \[^\r\n\]* (A::)?A \[^\r\n\]*\r\n#1 \[^\r\n\]* main \[^\r\n\]*" \
 	 "bt from A"
 
 gdb_continue_to_breakpoint "next caller func" ".*func-line.*"
Index: testsuite/gdb.cp/member-ptr.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/member-ptr.exp,v
retrieving revision 1.11
diff -u -p -r1.11 member-ptr.exp
--- testsuite/gdb.cp/member-ptr.exp	1 Jan 2010 07:32:01 -0000	1.11
+++ testsuite/gdb.cp/member-ptr.exp	28 Jan 2010 23:27:23 -0000
@@ -420,7 +420,7 @@ gdb_test_multiple "ptype pmf" $name {
 
 set name "print pmf"
 gdb_test_multiple "print pmf" $name {
-    -re "$vhn = $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
+    -re "$vhn = \\(int \\(A::\\*\\)\\(A \\*, int\\)\\) $hex <A::bar\\(int\\)>\r\n$gdb_prompt $" {
 	pass $name
     }
     -re "$vhn = .*not supported with HP aCC.*\r\n$gdb_prompt $" {
@@ -608,6 +608,8 @@ gdb_test_multiple "print (a.*pmf)(3)" $n
     }
 }
 
+gdb_test "ptype a.*pmf" "type = int \\(A \\*, int\\)"
+
 # Print out a pointer to data member which requires looking into
 # a base class.
 gdb_test "print diamond_pmi" "$vhn = &Base::x"
@@ -658,5 +660,5 @@ gdb_test "print null_pmi = &A::j" "$vhn 
 gdb_test "print null_pmi = 0" "$vhn = NULL"
 
 gdb_test "print null_pmf" "$vhn = NULL"
-gdb_test "print null_pmf = &A::foo" "$vhn = $hex <A::foo ?\\(int\\)>"
+gdb_test "print null_pmf = &A::foo" "$vhn = \\(int \\(A::\\*\\)\\(A \\*, int\\)\\) $hex <A::foo ?\\(int\\)>"
 gdb_test "print null_pmf = 0" "$vhn = NULL"
Index: testsuite/gdb.cp/overload.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/overload.exp,v
retrieving revision 1.13
diff -u -p -r1.13 overload.exp
--- testsuite/gdb.cp/overload.exp	1 Jan 2010 07:32:01 -0000	1.13
+++ testsuite/gdb.cp/overload.exp	28 Jan 2010 23:27:26 -0000
@@ -74,12 +74,12 @@ set re_methods	"${re_methods}${ws}int ov
 set re_methods	"${re_methods}${ws}int overload1arg\\(char\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(signed char\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(unsigned char\\);"
-set re_methods	"${re_methods}${ws}int overload1arg\\(short\\);"
-set re_methods	"${re_methods}${ws}int overload1arg\\(unsigned short\\);"
+set re_methods	"${re_methods}${ws}int overload1arg\\(short( int)?\\);"
+set re_methods	"${re_methods}${ws}int overload1arg\\((unsigned short|short unsigned)( int)?\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(int\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(unsigned int\\);"
-set re_methods	"${re_methods}${ws}int overload1arg\\(long\\);"
-set re_methods	"${re_methods}${ws}int overload1arg\\(unsigned long\\);"
+set re_methods	"${re_methods}${ws}int overload1arg\\(long( int)?\\);"
+set re_methods	"${re_methods}${ws}int overload1arg\\((unsigned long|long unsigned)( int)?\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(float\\);"
 set re_methods	"${re_methods}${ws}int overload1arg\\(double\\);"
 set re_methods	"${re_methods}${ws}int overloadfnarg\\((void|)\\);"
Index: testsuite/gdb.cp/ovldbreak.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/ovldbreak.exp,v
retrieving revision 1.12
diff -u -p -r1.12 ovldbreak.exp
--- testsuite/gdb.cp/ovldbreak.exp	1 Jan 2010 07:32:01 -0000	1.12
+++ testsuite/gdb.cp/ovldbreak.exp	28 Jan 2010 23:27:29 -0000
@@ -23,7 +23,8 @@
 # overloaded member functions
 #
 
-
+global timeout
+set timeout 15
 if $tracelevel then {
         strace $tracelevel
         }
@@ -127,10 +128,24 @@ proc set_bp_overloaded {name expectedmen
 }
 
 # This is the expected menu for overload1arg.
-# Note the arg type variations on lines 6 and 13.
+# Note the arg type variations for void and integer types.
 # This accommodates different versions of g++.
 
-set menu_overload1arg "\\\[0\\\] cancel\r\n\\\[1\\\] all\r\n\\\[2\\\] foo::overload1arg\\(double\\) at.*$srcfile:121\r\n\\\[3\\\] foo::overload1arg\\(float\\) at.*$srcfile:120\r\n\\\[4\\\] foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r\n\\\[5\\\] foo::overload1arg\\(long\\) at.*$srcfile:118\r\n\\\[6\\\] foo::overload1arg\\((unsigned int|unsigned)\\) at.*$srcfile:117\r\n\\\[7\\\] foo::overload1arg\\(int\\) at.*$srcfile:116\r\n\\\[8\\\] foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r\n\\\[9\\\] foo::overload1arg\\(short\\) at.*$srcfile:114\r\n\\\[10\\\] foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r\n\\\[11\\\] foo::overload1arg\\(signed char\\) at.*$srcfile:112\r\n\\\[12\\\] foo::overload1arg\\(char\\) at.*$srcfile:111\r\n\\\[13\\\] foo::overload1arg\\((void|)\\) at.*$srcfile:110\r\n> $"
+set    menu_overload1arg "\\\[0\\\] cancel\r\n"
+append menu_overload1arg "\\\[1\\\] all\r\n"
+append menu_overload1arg "\\\[2\\\] foo::overload1arg\\(double\\) at.*$srcfile:121\r\n"
+append menu_overload1arg "\\\[3\\\] foo::overload1arg\\(float\\) at.*$srcfile:120\r\n"
+append menu_overload1arg "\\\[4\\\] foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r\n"
+append menu_overload1arg "\\\[5\\\] foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r\n"
+append menu_overload1arg "\\\[6\\\] foo::overload1arg\\((unsigned int|unsigned)\\) at.*$srcfile:117\r\n"
+append menu_overload1arg "\\\[7\\\] foo::overload1arg\\(int\\) at.*$srcfile:116\r\n"
+append menu_overload1arg "\\\[8\\\] foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r\n"
+append menu_overload1arg "\\\[9\\\] foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r\n"
+append menu_overload1arg "\\\[10\\\] foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r\n"
+append menu_overload1arg "\\\[11\\\] foo::overload1arg\\(signed char\\) at.*$srcfile:112\r\n"
+append menu_overload1arg "\\\[12\\\] foo::overload1arg\\(char\\) at.*$srcfile:111\r\n"
+append menu_overload1arg "\\\[13\\\] foo::overload1arg\\((void|)\\) at.*$srcfile:110\r\n"
+append menu_overload1arg "> $"
 
 # Set multiple-symbols to "ask", to allow us to test the use
 # of the multiple-choice menu when breaking on an overloaded method.
@@ -157,17 +172,17 @@ set_bp_overloaded "foo::overload1arg" "$
 
 gdb_test "info break" \
     "Num     Type\[\t \]+Disp Enb Address\[\t \]+What.*
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in main at.*$srcfile:49\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in main(\\((|void)\\))? at.*$srcfile:49\r
 \[\t \]+breakpoint already hit 1 time\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((void|)\\) at.*$srcfile:110" \
@@ -215,17 +230,17 @@ gdb_expect {
 
 gdb_test "info break" \
     "Num     Type\[\t \]+Disp Enb Address\[\t \]+What.*
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in main at.*$srcfile:49\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in main(\\((|void)\\))? at.*$srcfile:49\r
 \[\t \]+breakpoint already hit 1 time\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((void|)\\) at.*$srcfile:110" \
@@ -296,12 +311,12 @@ gdb_test "info break" \
     "Num     Type\[\t \]+Disp Enb Address\[\t \]+What.*
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(double\\) at.*$srcfile:121\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(float\\) at.*$srcfile:120\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned long\\) at.*$srcfile:119\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long\\) at.*$srcfile:118\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned long|long unsigned)( int)?\\) at.*$srcfile:119\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(long( int)?\\) at.*$srcfile:118\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned|unsigned int)\\) at.*$srcfile:117\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(int\\) at.*$srcfile:116\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned short\\) at.*$srcfile:115\r
-\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short\\) at.*$srcfile:114\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\((unsigned short|short unsigned)( int)?\\) at.*$srcfile:115\r
+\[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(short( int)?\\) at.*$srcfile:114\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(unsigned char\\) at.*$srcfile:113\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(signed char\\) at.*$srcfile:112\r
 \[0-9\]+\[\t \]+breakpoint     keep y\[\t \]+$hex\[\t \]+in foo::overload1arg\\(char\\) at.*$srcfile:111\r
Index: testsuite/gdb.cp/exception.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.cp/exception.exp,v
retrieving revision 1.16
diff -u -p -r1.16 exception.exp
--- testsuite/gdb.cp/exception.exp	1 Jan 2010 07:32:01 -0000	1.16
+++ testsuite/gdb.cp/exception.exp	28 Jan 2010 23:27:32 -0000
@@ -146,7 +146,9 @@ gdb_test_multiple "continue" $name {
 
 set name "backtrace after first throw"
 gdb_test_multiple "backtrace" $name {
-    -re ".*#\[0-9\]+${ws}($hex in |)__cxa_throw.*#\[0-9\]+${ws}$hex in foo \\(i=20\\) at .*${srcfile}:\[0-9\]+\r\n#\[0-9\]+${ws}$hex in main \\(.*\\) at .*${srcfile}:\[0-9\]+\r\n$gdb_prompt $" {
+    -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_throw\[\[:>:\]\].*#\[0-9\]+${ws}$hex in foo \\(i=20\\) at .*${srcfile}:\[0-9\]+\r\n#\[0-9\]+${ws}$hex in main \\(.*\\) at .*${srcfile}:\[0-9\]+\r\n$gdb_prompt $" {
+	# Either __cxxabiv1::__cxa_throw or __cxa_throw can be printed
+	# depending on debug info presence.
 	pass $name
     }
 }
@@ -168,7 +170,7 @@ gdb_test_multiple "continue" $name {
 
 set name "backtrace after first catch"
 gdb_test_multiple "backtrace" $name {
-    -re ".*#\[0-9\]+${ws}($hex in |)__cxa_begin_catch.*#\[0-9\]+${ws}$hex in main \\(.*\\) at .*$srcfile:\[0-9\]+\r\n$gdb_prompt $" {
+    -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_begin_catch\[\[:>:\]\].*#\[0-9\]+${ws}$hex in main \\(.*\\) at .*$srcfile:\[0-9\]+\r\n$gdb_prompt $" {
 	pass $name
     }
 }
@@ -190,7 +192,7 @@ gdb_test_multiple "continue" $name {
 
 set name "backtrace after second throw"
 gdb_test_multiple "backtrace" $name {
-    -re ".*#\[0-9\]+${ws}($hex in |)__cxa_throw.*#\[0-9\]+${ws}$hex in foo \\(i=20\\) at .*${srcfile}:\[0-9\]+\r\n#\[0-9\]+${ws}$hex in main \\(.*\\) at .*${srcfile}:\[0-9\]+\r\n$gdb_prompt $" {
+    -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_throw\[\[:>:\]\].*#\[0-9\]+${ws}$hex in foo \\(i=20\\) at .*${srcfile}:\[0-9\]+\r\n#\[0-9\]+${ws}$hex in main \\(.*\\) at .*${srcfile}:\[0-9\]+\r\n$gdb_prompt $" {
 	pass $name
     }
 }
@@ -212,7 +214,7 @@ gdb_test_multiple "continue" $name {
 
 set name "backtrace after second catch"
 gdb_test_multiple "backtrace" $name {
-    -re ".*#\[0-9\]+${ws}($hex in |)__cxa_begin_catch.*#\[0-9\]+${ws}$hex in main \\(.*\\) at .*$srcfile:\[0-9\]+\r\n$gdb_prompt $" {
+    -re ".*#\[0-9\]+.*\[\[:<:\]\]__cxa_begin_catch\[\[:>:\]\].*#\[0-9\]+${ws}$hex in main \\(.*\\) at .*$srcfile:\[0-9\]+\r\n$gdb_prompt $" {
 	pass $name
     }
 }
Index: testsuite/gdb.java/jmain.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.java/jmain.exp,v
retrieving revision 1.11
diff -u -p -r1.11 jmain.exp
--- testsuite/gdb.java/jmain.exp	1 Jan 2010 07:32:03 -0000	1.11
+++ testsuite/gdb.java/jmain.exp	28 Jan 2010 23:27:35 -0000
@@ -65,7 +65,7 @@ gdb_test "break jmain.main" "${bpmain}"
 
 # Check that a fully qualified "main" works.
 gdb_load "${binfile}"
-set cmd "break \'${testfile}.main(java.lang.String\[\])\'"
+set cmd "break ${testfile}.main(java.lang.String\[\])"
 set msg $cmd
 gdb_test_multiple $cmd $msg {
     -re "${bpmain}\r\n$gdb_prompt $" {
@@ -79,7 +79,7 @@ gdb_test_multiple $cmd $msg {
 	gdb_test "n" "" ""
 
 	# Check again with a method signature at the end.
-	set cmd "break \'${testfile}.main(java.lang.String\[\])void\'"
+	set cmd "break ${testfile}.main(java.lang.String\[\])void"
 	set msg $cmd
 	gdb_test_multiple $cmd $msg {
 	    -re "${bpmain}\r\n$gdb_prompt $" {
Index: testsuite/gdb.java/jmisc.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.java/jmisc.exp,v
retrieving revision 1.14
diff -u -p -r1.14 jmisc.exp
--- testsuite/gdb.java/jmisc.exp	1 Jan 2010 07:32:03 -0000	1.14
+++ testsuite/gdb.java/jmisc.exp	28 Jan 2010 23:27:38 -0000
@@ -71,8 +71,8 @@ if ![set_lang_java] then {
     # signature.
     runto_main
     set function "${testfile}.main(java.lang.String\[\])"
-    gdb_breakpoint "\'$function\'" { allow-pending }
-    gdb_breakpoint "\'${function}void\'" { allow-pending }
+    gdb_breakpoint "$function" { allow-pending }
+    gdb_breakpoint "${function}void" { allow-pending }
     gdb_continue_to_breakpoint $function
 
     send_gdb "ptype jmisc\n"   
Index: testsuite/gdb.java/jprint.exp
===================================================================
RCS file: /cvs/src/src/gdb/testsuite/gdb.java/jprint.exp,v
retrieving revision 1.10
diff -u -p -r1.10 jprint.exp
--- testsuite/gdb.java/jprint.exp	1 Jan 2010 07:32:03 -0000	1.10
+++ testsuite/gdb.java/jprint.exp	28 Jan 2010 23:27:41 -0000
@@ -70,8 +70,8 @@ if ![set_lang_java] then {
     # signature.
     runto_main
     set function "${testfile}.main(java.lang.String\[\])"
-    gdb_breakpoint "\'$function\'" { allow-pending }
-    gdb_breakpoint "\'${function}void\'" { allow-pending }
+    gdb_breakpoint "$function" { allow-pending }
+    gdb_breakpoint "${function}void" { allow-pending }
     gdb_continue_to_breakpoint $function
 
     gdb_test "p jvclass.addprint(4,5,6)" "sum is 15\r\n.*" "unambiguous static call"

[-- Attachment #6: dwarf2_physname-trivial-2.patch --]
[-- Type: text/plain, Size: 37339 bytes --]

Index: ax-gdb.c
===================================================================
RCS file: /cvs/src/src/gdb/ax-gdb.c,v
retrieving revision 1.61
diff -u -p -r1.61 ax-gdb.c
--- ax-gdb.c	15 Jan 2010 22:37:17 -0000	1.61
+++ ax-gdb.c	28 Jan 2010 23:15:00 -0000
@@ -1810,7 +1810,7 @@ gen_expr (struct expression *exp, union 
 
 	/* Calling lookup_block_symbol is necessary to get the LOC_REGISTER
 	   symbol instead of the LOC_ARG one (if both exist).  */
-	sym = lookup_block_symbol (b, this_name, NULL, VAR_DOMAIN);
+	sym = lookup_block_symbol (b, this_name, VAR_DOMAIN);
 	if (!sym)
 	  error (_("no `%s' found"), this_name);
 
Index: ada-lang.c
===================================================================
RCS file: /cvs/src/src/gdb/ada-lang.c,v
retrieving revision 1.247
diff -u -p -r1.247 ada-lang.c
--- ada-lang.c	20 Jan 2010 03:34:25 -0000	1.247
+++ ada-lang.c	28 Jan 2010 23:15:06 -0000
@@ -4781,14 +4781,10 @@ ada_lookup_symbol (const char *name, con
 
 static struct symbol *
 ada_lookup_symbol_nonlocal (const char *name,
-                            const char *linkage_name,
                             const struct block *block,
                             const domain_enum domain)
 {
-  if (linkage_name == NULL)
-    linkage_name = name;
-  return ada_lookup_symbol (linkage_name, block_static_block (block), domain,
-                            NULL);
+  return ada_lookup_symbol (name, block_static_block (block), domain, NULL);
 }
 
 
Index: cp-namespace.c
===================================================================
RCS file: /cvs/src/src/gdb/cp-namespace.c,v
retrieving revision 1.33
diff -u -p -r1.33 cp-namespace.c
--- cp-namespace.c	26 Jan 2010 16:47:34 -0000	1.33
+++ cp-namespace.c	28 Jan 2010 23:15:09 -0000
@@ -34,14 +34,12 @@
 #include "buildsym.h"
 
 static struct symbol *lookup_namespace_scope (const char *name,
-					      const char *linkage_name,
 					      const struct block *block,
 					      const domain_enum domain,
 					      const char *scope,
 					      int scope_len);
 
 static struct symbol *lookup_symbol_file (const char *name,
-					  const char *linkage_name,
 					  const struct block *block,
 					  const domain_enum domain,
 					  int anonymous_namespace);
@@ -223,26 +221,23 @@ cp_add_using (const char *dest,
 /* The C++-specific version of name lookup for static and global
    names.  This makes sure that names get looked for in all namespaces
    that are in scope.  NAME is the natural name of the symbol that
-   we're looking for, LINKAGE_NAME (which is optional) is its linkage
-   name, BLOCK is the block that we're searching within, DOMAIN says
-   what kind of symbols we're looking for, and if SYMTAB is non-NULL,
-   we should store the symtab where we found the symbol in it.  */
+   we're looking for, BLOCK is the block that we're searching within,
+   DOMAIN says what kind of symbols we're looking for, and if SYMTAB is
+   non-NULL, we should store the symtab where we found the symbol in it.  */
 
 struct symbol *
 cp_lookup_symbol_nonlocal (const char *name,
-			   const char *linkage_name,
 			   const struct block *block,
 			   const domain_enum domain)
 {
   struct symbol *sym;
   const char *scope = block_scope (block);
 
-  sym = lookup_namespace_scope (name, linkage_name, block, domain, scope, 0);
+  sym = lookup_namespace_scope (name, block, domain, scope, 0);
   if (sym != NULL)
     return sym;
 
-  return cp_lookup_symbol_namespace (scope, name, linkage_name, block, domain,
-                                     1);
+  return cp_lookup_symbol_namespace (scope, name, block, domain, 1);
 }
 
 /* Look up NAME in the C++ namespace NAMESPACE. Other arguments are as in
@@ -251,14 +246,12 @@ cp_lookup_symbol_nonlocal (const char *n
 static struct symbol *
 cp_lookup_symbol_in_namespace (const char *namespace,
                                const char *name,
-                               const char *linkage_name,
                                const struct block *block,
                                const domain_enum domain)
 {
   if (namespace[0] == '\0')
     {
-      return lookup_symbol_file (name, linkage_name, block,
-                                 domain, 0);
+      return lookup_symbol_file (name, block, domain, 0);
     }
   else
     {
@@ -267,8 +260,8 @@ cp_lookup_symbol_in_namespace (const cha
       strcpy (concatenated_name, namespace);
       strcat (concatenated_name, "::");
       strcat (concatenated_name, name);
-      return lookup_symbol_file (concatenated_name, linkage_name,
-                                 block, domain,cp_is_anonymous (namespace));
+      return lookup_symbol_file (concatenated_name, block,
+				 domain,cp_is_anonymous (namespace));
     }
 }
 
@@ -302,7 +295,6 @@ reset_directive_searched (void *data)
 static struct symbol *
 cp_lookup_symbol_imports (const char *scope,
                           const char *name,
-                          const char *linkage_name,
                           const struct block *block,
                           const domain_enum domain,
                           const int search_parents)
@@ -314,8 +306,7 @@ cp_lookup_symbol_imports (const char *sc
   struct cleanup *searched_cleanup;
 
   /* First, try to find the symbol in the given namespace.  */
-  sym = cp_lookup_symbol_in_namespace (scope, name, linkage_name, block,
-                                       domain);
+  sym = cp_lookup_symbol_in_namespace (scope, name, block, domain);
   if (sym != NULL)
     return sym;
 
@@ -346,7 +337,6 @@ cp_lookup_symbol_imports (const char *sc
 
 	sym = cp_lookup_symbol_namespace (current->import_src,
 	                                  name,
-	                                  linkage_name,
 	                                  block,
 	                                  domain,
 	                                  0);
@@ -369,7 +359,6 @@ cp_lookup_symbol_imports (const char *sc
 struct symbol*
 cp_lookup_symbol_namespace (const char *scope,
                             const char *name,
-                            const char *linkage_name,
                             const struct block *block,
                             const domain_enum domain,
                             const int search_parents)
@@ -379,7 +368,7 @@ cp_lookup_symbol_namespace (const char *
   /* Search for name in namespaces imported to this and parent blocks.  */
   while (block != NULL)
     {
-      sym = cp_lookup_symbol_imports (scope, name, linkage_name, block, domain,
+      sym = cp_lookup_symbol_imports (scope, name, block, domain,
                                       search_parents);
 
       if (sym)
@@ -408,7 +397,6 @@ cp_lookup_symbol_namespace (const char *
 
 static struct symbol *
 lookup_namespace_scope (const char *name,
-			const char *linkage_name,
 			const struct block *block,
 			const domain_enum domain,
 			const char *scope,
@@ -430,8 +418,7 @@ lookup_namespace_scope (const char *name
 	  new_scope_len += 2;
 	}
       new_scope_len += cp_find_first_component (scope + new_scope_len);
-      sym = lookup_namespace_scope (name, linkage_name, block,
-				    domain, scope, new_scope_len);
+      sym = lookup_namespace_scope (name, block, domain, scope, new_scope_len);
       if (sym != NULL)
 	return sym;
     }
@@ -442,8 +429,7 @@ lookup_namespace_scope (const char *name
   namespace = alloca (scope_len + 1);
   strncpy (namespace, scope, scope_len);
   namespace[scope_len] = '\0';
-  return cp_lookup_symbol_in_namespace (namespace, name, linkage_name,
-                                        block, domain);
+  return cp_lookup_symbol_in_namespace (namespace, name, block, domain);
 }
 
 /* Look up NAME in BLOCK's static block and in global blocks.  If
@@ -453,14 +439,13 @@ lookup_namespace_scope (const char *name
 
 static struct symbol *
 lookup_symbol_file (const char *name,
-		    const char *linkage_name,
 		    const struct block *block,
 		    const domain_enum domain,
 		    int anonymous_namespace)
 {
   struct symbol *sym = NULL;
 
-  sym = lookup_symbol_static (name, linkage_name, block, domain);
+  sym = lookup_symbol_static (name, block, domain);
   if (sym != NULL)
     return sym;
 
@@ -473,12 +458,11 @@ lookup_symbol_file (const char *name,
       const struct block *global_block = block_global_block (block);
       
       if (global_block != NULL)
-	sym = lookup_symbol_aux_block (name, linkage_name, global_block,
-				       domain);
+	sym = lookup_symbol_aux_block (name, global_block, domain);
     }
   else
     {
-      sym = lookup_symbol_global (name, linkage_name, block, domain);
+      sym = lookup_symbol_global (name, block, domain);
     }
 
   if (sym != NULL)
@@ -528,7 +512,6 @@ cp_lookup_nested_type (struct type *pare
 	const char *parent_name = TYPE_TAG_NAME (parent_type);
 	struct symbol *sym = cp_lookup_symbol_in_namespace (parent_name,
 	                                                    nested_name,
-	                                                    NULL,
 	                                                    block,
 	                                                    VAR_DOMAIN);
 	if (sym == NULL || SYMBOL_CLASS (sym) != LOC_TYPEDEF)
@@ -774,7 +757,7 @@ check_one_possible_namespace_symbol (con
 
   memcpy (name_copy, name, len);
   name_copy[len] = '\0';
-  sym = lookup_block_symbol (block, name_copy, NULL, VAR_DOMAIN);
+  sym = lookup_block_symbol (block, name_copy, VAR_DOMAIN);
 
   if (sym == NULL)
     {
@@ -815,7 +798,7 @@ lookup_possible_namespace_symbol (const 
       struct symbol *sym;
 
       sym = lookup_block_symbol (get_possible_namespace_block (objfile),
-				 name, NULL, VAR_DOMAIN);
+				 name, VAR_DOMAIN);
 
       if (sym != NULL)
 	return sym;
Index: cp-support.c
===================================================================
RCS file: /cvs/src/src/gdb/cp-support.c,v
retrieving revision 1.35
diff -u -p -r1.35 cp-support.c
--- cp-support.c	1 Jan 2010 07:31:30 -0000	1.35
+++ cp-support.c	28 Jan 2010 23:15:13 -0000
@@ -840,9 +840,9 @@ read_in_psymtabs (const char *func_name)
     if (ps->readin)
       continue;
 
-    if ((lookup_partial_symbol (ps, func_name, NULL, 1, VAR_DOMAIN)
+    if ((lookup_partial_symbol (ps, func_name, 1, VAR_DOMAIN)
 	 != NULL)
-	|| (lookup_partial_symbol (ps, func_name, NULL, 0, VAR_DOMAIN)
+	|| (lookup_partial_symbol (ps, func_name, 0, VAR_DOMAIN)
 	    != NULL))
       psymtab_to_symtab (ps);
   }
Index: cp-support.h
===================================================================
RCS file: /cvs/src/src/gdb/cp-support.h,v
retrieving revision 1.32
diff -u -p -r1.32 cp-support.h
--- cp-support.h	26 Jan 2010 16:47:34 -0000	1.32
+++ cp-support.h	28 Jan 2010 23:15:16 -0000
@@ -102,13 +102,11 @@ extern void cp_set_block_scope (const st
 extern void cp_scan_for_anonymous_namespaces (const struct symbol *symbol);
 
 extern struct symbol *cp_lookup_symbol_nonlocal (const char *name,
-						 const char *linkage_name,
 						 const struct block *block,
 						 const domain_enum domain);
 
 extern struct symbol *cp_lookup_symbol_namespace (const char *namespace,
 						  const char *name,
-						  const char *linkage_name,
 						  const struct block *block,
 						  const domain_enum domain,
 						  const int search_parents);
Index: language.h
===================================================================
RCS file: /cvs/src/src/gdb/language.h,v
retrieving revision 1.62
diff -u -p -r1.62 language.h
--- language.h	14 Jan 2010 08:03:36 -0000	1.62
+++ language.h	28 Jan 2010 23:15:19 -0000
@@ -237,7 +237,6 @@ struct language_defn
        variables.  */
 
     struct symbol *(*la_lookup_symbol_nonlocal) (const char *,
-						 const char *,
 						 const struct block *,
 						 const domain_enum);
 
Index: scm-valprint.c
===================================================================
RCS file: /cvs/src/src/gdb/scm-valprint.c,v
retrieving revision 1.29
diff -u -p -r1.29 scm-valprint.c
--- scm-valprint.c	1 Jan 2010 07:31:41 -0000	1.29
+++ scm-valprint.c	28 Jan 2010 23:15:26 -0000
@@ -62,9 +62,9 @@ scm_inferior_print (struct type *type, L
     {
       /* XXX: Should we cache these symbols?  */
       gdb_output_sym =
-	lookup_symbol_global ("gdb_output", NULL, NULL, VAR_DOMAIN);
+	lookup_symbol_global ("gdb_output", NULL, VAR_DOMAIN);
       gdb_output_len_sym =
-	lookup_symbol_global ("gdb_output_length", NULL, NULL, VAR_DOMAIN);
+	lookup_symbol_global ("gdb_output_length", NULL, VAR_DOMAIN);
 
       if ((gdb_output_sym == NULL) || (gdb_output_len_sym == NULL))
 	ret = -1;
Index: solib-darwin.c
===================================================================
RCS file: /cvs/src/src/gdb/solib-darwin.c,v
retrieving revision 1.11
diff -u -p -r1.11 solib-darwin.c
--- solib-darwin.c	8 Jan 2010 22:52:03 -0000	1.11
+++ solib-darwin.c	28 Jan 2010 23:15:29 -0000
@@ -408,7 +408,6 @@ darwin_relocate_section_addresses (struc
 static struct symbol *
 darwin_lookup_lib_symbol (const struct objfile *objfile,
 			  const char *name,
-			  const char *linkage_name,
 			  const domain_enum domain)
 {
   return NULL;
Index: solib-svr4.c
===================================================================
RCS file: /cvs/src/src/gdb/solib-svr4.c,v
retrieving revision 1.116
diff -u -p -r1.116 solib-svr4.c
--- solib-svr4.c	27 Jan 2010 00:32:09 -0000	1.116
+++ solib-svr4.c	28 Jan 2010 23:15:32 -0000
@@ -1961,7 +1961,6 @@ struct target_so_ops svr4_so_ops;
 static struct symbol *
 elf_lookup_lib_symbol (const struct objfile *objfile,
 		       const char *name,
-		       const char *linkage_name,
 		       const domain_enum domain)
 {
   bfd *abfd;
@@ -1979,8 +1978,7 @@ elf_lookup_lib_symbol (const struct objf
   if (abfd == NULL || scan_dyntag (DT_SYMBOLIC, abfd, NULL) != 1)
     return NULL;
 
-  return lookup_global_symbol_from_objfile
-		(objfile, name, linkage_name, domain);
+  return lookup_global_symbol_from_objfile (objfile, name, domain);
 }
 
 extern initialize_file_ftype _initialize_svr4_solib; /* -Wmissing-prototypes */
Index: solib.c
===================================================================
RCS file: /cvs/src/src/gdb/solib.c,v
retrieving revision 1.133
diff -u -p -r1.133 solib.c
--- solib.c	20 Jan 2010 14:23:07 -0000	1.133
+++ solib.c	28 Jan 2010 23:15:35 -0000
@@ -1154,13 +1154,12 @@ show_auto_solib_add (struct ui_file *fil
 struct symbol *
 solib_global_lookup (const struct objfile *objfile,
 		     const char *name,
-		     const char *linkage_name,
 		     const domain_enum domain)
 {
   struct target_so_ops *ops = solib_ops (target_gdbarch);
 
   if (ops->lookup_lib_global_symbol != NULL)
-    return ops->lookup_lib_global_symbol (objfile, name, linkage_name, domain);
+    return ops->lookup_lib_global_symbol (objfile, name, domain);
   return NULL;
 }
 
Index: solist.h
===================================================================
RCS file: /cvs/src/src/gdb/solist.h,v
retrieving revision 1.29
diff -u -p -r1.29 solist.h
--- solist.h	8 Jan 2010 22:52:04 -0000	1.29
+++ solist.h	28 Jan 2010 23:15:38 -0000
@@ -117,7 +117,6 @@ struct target_so_ops
     /* Hook for looking up global symbols in a library-specific way.  */
     struct symbol * (*lookup_lib_global_symbol) (const struct objfile *objfile,
 						 const char *name,
-						 const char *linkage_name,
 						 const domain_enum domain);
 
     /* Given two so_list objects, one from the GDB thread list
@@ -157,7 +156,6 @@ extern struct target_so_ops *current_tar
 /* Handler for library-specific global symbol lookup in solib.c.  */
 struct symbol *solib_global_lookup (const struct objfile *objfile,
 				    const char *name,
-				    const char *linkage_name,
 				    const domain_enum domain);
 
 #endif
Index: symmisc.c
===================================================================
RCS file: /cvs/src/src/gdb/symmisc.c,v
retrieving revision 1.67
diff -u -p -r1.67 symmisc.c
--- symmisc.c	1 Jan 2010 07:31:42 -0000	1.67
+++ symmisc.c	28 Jan 2010 23:15:42 -0000
@@ -1143,7 +1143,7 @@ maintenance_check_symtabs (char *ignore,
     while (length--)
       {
 	sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym),
-				   NULL, SYMBOL_DOMAIN (*psym));
+				   SYMBOL_DOMAIN (*psym));
 	if (!sym)
 	  {
 	    printf_filtered ("Static symbol `");
@@ -1160,7 +1160,7 @@ maintenance_check_symtabs (char *ignore,
     while (length--)
       {
 	sym = lookup_block_symbol (b, SYMBOL_LINKAGE_NAME (*psym),
-				   NULL, SYMBOL_DOMAIN (*psym));
+				   SYMBOL_DOMAIN (*psym));
 	if (!sym)
 	  {
 	    printf_filtered ("Global symbol `");
Index: symtab.c
===================================================================
RCS file: /cvs/src/src/gdb/symtab.c,v
retrieving revision 1.224
diff -u -p -r1.224 symtab.c
--- symtab.c	26 Jan 2010 15:48:25 -0000	1.224
+++ symtab.c	28 Jan 2010 23:15:46 -0000
@@ -85,7 +86,6 @@ static int find_line_common (struct line
 char *operator_chars (char *p, char **end);
 
 static struct symbol *lookup_symbol_aux (const char *name,
-					 const char *linkage_name,
 					 const struct block *block,
 					 const domain_enum domain,
 					 enum language language,
@@ -93,20 +93,17 @@ static struct symbol *lookup_symbol_aux 
 
 static
 struct symbol *lookup_symbol_aux_local (const char *name,
-					const char *linkage_name,
 					const struct block *block,
 					const domain_enum domain);
 
 static
 struct symbol *lookup_symbol_aux_symtabs (int block_index,
 					  const char *name,
-					  const char *linkage_name,
 					  const domain_enum domain);
 
 static
 struct symbol *lookup_symbol_aux_psymtabs (int block_index,
 					   const char *name,
-					   const char *linkage_name,
 					   const domain_enum domain);
 
 static int file_matches (char *, char **, int);
@@ -1257,7 +1254,6 @@ lookup_symbol_in_language (const char *n
 {
   char *demangled_name = NULL;
   const char *modified_name = NULL;
-  const char *mangled_name = NULL;
   struct symbol *returnval;
   struct cleanup *cleanup = make_cleanup (null_cleanup, 0);
 
@@ -1270,7 +1266,6 @@ lookup_symbol_in_language (const char *n
       demangled_name = cplus_demangle (name, DMGL_ANSI | DMGL_PARAMS);
       if (demangled_name)
 	{
-	  mangled_name = name;
 	  modified_name = demangled_name;
 	  make_cleanup (xfree, demangled_name);
 	}
@@ -1292,7 +1287,6 @@ lookup_symbol_in_language (const char *n
 		      		       DMGL_ANSI | DMGL_PARAMS | DMGL_JAVA);
       if (demangled_name)
 	{
-	  mangled_name = name;
 	  modified_name = demangled_name;
 	  make_cleanup (xfree, demangled_name);
 	}
@@ -1311,8 +1305,8 @@ lookup_symbol_in_language (const char *n
       modified_name = copy;
     }
 
-  returnval = lookup_symbol_aux (modified_name, mangled_name, block,
-				 domain, lang, is_a_field_of_this);
+  returnval = lookup_symbol_aux (modified_name, block, domain, lang,
+				 is_a_field_of_this);
   do_cleanups (cleanup);
 
   return returnval;
@@ -1336,9 +1330,9 @@ lookup_symbol (const char *name, const s
    well.  */
 
 static struct symbol *
-lookup_symbol_aux (const char *name, const char *linkage_name,
-		   const struct block *block, const domain_enum domain,
-		   enum language language, int *is_a_field_of_this)
+lookup_symbol_aux (const char *name, const struct block *block,
+		   const domain_enum domain, enum language language,
+		   int *is_a_field_of_this)
 {
   struct symbol *sym;
   const struct language_defn *langdef;
@@ -1354,7 +1348,7 @@ lookup_symbol_aux (const char *name, con
   /* Search specified block and its superiors.  Don't search
      STATIC_BLOCK or GLOBAL_BLOCK.  */
 
-  sym = lookup_symbol_aux_local (name, linkage_name, block, domain);
+  sym = lookup_symbol_aux_local (name, block, domain);
   if (sym != NULL)
     return sym;
 
@@ -1375,7 +1369,7 @@ lookup_symbol_aux (const char *name, con
 
       if (function_block && !dict_empty (BLOCK_DICT (function_block)))
 	sym = lookup_block_symbol (function_block, langdef->la_name_of_this,
-				   NULL, VAR_DOMAIN);
+				   VAR_DOMAIN);
       if (sym)
 	{
 	  struct type *t = sym->type;
@@ -1403,7 +1397,7 @@ lookup_symbol_aux (const char *name, con
   /* Now do whatever is appropriate for LANGUAGE to look
      up static and global variables.  */
 
-  sym = langdef->la_lookup_symbol_nonlocal (name, linkage_name, block, domain);
+  sym = langdef->la_lookup_symbol_nonlocal (name, block, domain);
   if (sym != NULL)
     return sym;
 
@@ -1413,11 +1407,11 @@ lookup_symbol_aux (const char *name, con
      desired name as a file-level static, then do psymtab-to-symtab
      conversion on the fly and return the found symbol. */
 
-  sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, linkage_name, domain);
+  sym = lookup_symbol_aux_symtabs (STATIC_BLOCK, name, domain);
   if (sym != NULL)
     return sym;
 
-  sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, linkage_name, domain);
+  sym = lookup_symbol_aux_psymtabs (STATIC_BLOCK, name, domain);
   if (sym != NULL)
     return sym;
 
@@ -1428,8 +1422,7 @@ lookup_symbol_aux (const char *name, con
    Don't search STATIC_BLOCK or GLOBAL_BLOCK.  */
 
 static struct symbol *
-lookup_symbol_aux_local (const char *name, const char *linkage_name,
-			 const struct block *block,
+lookup_symbol_aux_local (const char *name, const struct block *block,
 			 const domain_enum domain)
 {
   struct symbol *sym;
@@ -1442,7 +1435,7 @@ lookup_symbol_aux_local (const char *nam
 
   while (block != static_block)
     {
-      sym = lookup_symbol_aux_block (name, linkage_name, block, domain);
+      sym = lookup_symbol_aux_block (name, block, domain);
       if (sym != NULL)
 	return sym;
 
@@ -1485,13 +1478,12 @@ lookup_objfile_from_block (const struct 
    block_found appropriately.  */
 
 struct symbol *
-lookup_symbol_aux_block (const char *name, const char *linkage_name,
-			 const struct block *block,
+lookup_symbol_aux_block (const char *name, const struct block *block,
 			 const domain_enum domain)
 {
   struct symbol *sym;
 
-  sym = lookup_block_symbol (block, name, linkage_name, domain);
+  sym = lookup_block_symbol (block, name, domain);
   if (sym)
     {
       block_found = block;
@@ -1507,7 +1499,6 @@ lookup_symbol_aux_block (const char *nam
 struct symbol *
 lookup_global_symbol_from_objfile (const struct objfile *main_objfile,
 				   const char *name,
-				   const char *linkage_name,
 				   const domain_enum domain)
 {
   const struct objfile *objfile;
@@ -1526,7 +1517,7 @@ lookup_global_symbol_from_objfile (const
         {
           bv = BLOCKVECTOR (s);
           block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-          sym = lookup_block_symbol (block, name, linkage_name, domain);
+          sym = lookup_block_symbol (block, name, domain);
           if (sym)
             {
               block_found = block;
@@ -1538,13 +1529,12 @@ lookup_global_symbol_from_objfile (const
       ALL_OBJFILE_PSYMTABS (objfile, ps)
         {
           if (!ps->readin
-              && lookup_partial_symbol (ps, name, linkage_name,
-                                        1, domain))
+              && lookup_partial_symbol (ps, name, 1, domain))
             {
               s = PSYMTAB_TO_SYMTAB (ps);
               bv = BLOCKVECTOR (s);
               block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-              sym = lookup_block_symbol (block, name, linkage_name, domain);
+              sym = lookup_block_symbol (block, name, domain);
               return fixup_symbol_section (sym, (struct objfile *)objfile);
             }
         }
@@ -1559,8 +1549,7 @@ lookup_global_symbol_from_objfile (const
    static symbols.  */
 
 static struct symbol *
-lookup_symbol_aux_symtabs (int block_index,
-			   const char *name, const char *linkage_name,
+lookup_symbol_aux_symtabs (int block_index, const char *name,
 			   const domain_enum domain)
 {
   struct symbol *sym;
@@ -1573,7 +1562,7 @@ lookup_symbol_aux_symtabs (int block_ind
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, block_index);
-    sym = lookup_block_symbol (block, name, linkage_name, domain);
+    sym = lookup_block_symbol (block, name, domain);
     if (sym)
       {
 	block_found = block;
@@ -1591,7 +1580,6 @@ lookup_symbol_aux_symtabs (int block_ind
 
 static struct symbol *
 lookup_symbol_aux_psymtabs (int block_index, const char *name,
-			    const char *linkage_name,
 			    const domain_enum domain)
 {
   struct symbol *sym;
@@ -1605,13 +1593,12 @@ lookup_symbol_aux_psymtabs (int block_in
   ALL_PSYMTABS (objfile, ps)
   {
     if (!ps->readin
-	&& lookup_partial_symbol (ps, name, linkage_name,
-				  psymtab_index, domain))
+	&& lookup_partial_symbol (ps, name, psymtab_index, domain))
       {
 	s = PSYMTAB_TO_SYMTAB (ps);
 	bv = BLOCKVECTOR (s);
 	block = BLOCKVECTOR_BLOCK (bv, block_index);
-	sym = lookup_block_symbol (block, name, linkage_name, domain);
+	sym = lookup_block_symbol (block, name, domain);
 	if (!sym)
 	  {
 	    /* This shouldn't be necessary, but as a last resort try
@@ -1628,7 +1615,7 @@ lookup_symbol_aux_psymtabs (int block_in
 	    block = BLOCKVECTOR_BLOCK (bv,
 				       block_index == GLOBAL_BLOCK ?
 				       STATIC_BLOCK : GLOBAL_BLOCK);
-	    sym = lookup_block_symbol (block, name, linkage_name, domain);
+	    sym = lookup_block_symbol (block, name, domain);
 	    if (!sym)
 	      error (_("Internal: %s symbol `%s' found in %s psymtab but not in symtab.\n%s may be an inlined function, or may be a template function\n(if a template, try specifying an instantiation: %s<type>)."),
 		     block_index == GLOBAL_BLOCK ? "global" : "static",
@@ -1647,7 +1634,6 @@ lookup_symbol_aux_psymtabs (int block_in
 
 struct symbol *
 basic_lookup_symbol_nonlocal (const char *name,
-			      const char *linkage_name,
 			      const struct block *block,
 			      const domain_enum domain)
 {
@@ -1681,11 +1667,11 @@ basic_lookup_symbol_nonlocal (const char
      than that one, so I don't think we should worry about that for
      now.  */
 
-  sym = lookup_symbol_static (name, linkage_name, block, domain);
+  sym = lookup_symbol_static (name, block, domain);
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_global (name, linkage_name, block, domain);
+  return lookup_symbol_global (name, block, domain);
 }
 
 /* Lookup a symbol in the static block associated to BLOCK, if there
@@ -1693,14 +1679,13 @@ basic_lookup_symbol_nonlocal (const char
 
 struct symbol *
 lookup_symbol_static (const char *name,
-		      const char *linkage_name,
 		      const struct block *block,
 		      const domain_enum domain)
 {
   const struct block *static_block = block_static_block (block);
 
   if (static_block != NULL)
-    return lookup_symbol_aux_block (name, linkage_name, static_block, domain);
+    return lookup_symbol_aux_block (name, static_block, domain);
   else
     return NULL;
 }
@@ -1710,7 +1695,6 @@ lookup_symbol_static (const char *name,
 
 struct symbol *
 lookup_symbol_global (const char *name,
-		      const char *linkage_name,
 		      const struct block *block,
 		      const domain_enum domain)
 {
@@ -1720,15 +1704,15 @@ lookup_symbol_global (const char *name,
   /* Call library-specific lookup procedure.  */
   objfile = lookup_objfile_from_block (block);
   if (objfile != NULL)
-    sym = solib_global_lookup (objfile, name, linkage_name, domain);
+    sym = solib_global_lookup (objfile, name, domain);
   if (sym != NULL)
     return sym;
 
-  sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, linkage_name, domain);
+  sym = lookup_symbol_aux_symtabs (GLOBAL_BLOCK, name, domain);
   if (sym != NULL)
     return sym;
 
-  return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, linkage_name, domain);
+  return lookup_symbol_aux_psymtabs (GLOBAL_BLOCK, name, domain);
 }
 
 int
@@ -1752,14 +1736,11 @@ symbol_matches_domain (enum language sym
 }
 
 /* Look, in partial_symtab PST, for symbol whose natural name is NAME.
-   If LINKAGE_NAME is non-NULL, check in addition that the symbol's
-   linkage name matches it.  Check the global symbols if GLOBAL, the
-   static symbols if not */
+   Check the global symbols if GLOBAL, the static symbols if not. */
 
 struct partial_symbol *
 lookup_partial_symbol (struct partial_symtab *pst, const char *name,
-		       const char *linkage_name, int global,
-		       domain_enum domain)
+		       int global, domain_enum domain)
 {
   struct partial_symbol *temp;
   struct partial_symbol **start, **psym;
@@ -1811,9 +1792,7 @@ lookup_partial_symbol (struct partial_sy
 	internal_error (__FILE__, __LINE__, _("failed internal consistency check"));
 
       while (top <= real_top
-	     && (linkage_name != NULL
-		 ? strcmp (SYMBOL_LINKAGE_NAME (*top), linkage_name) == 0
-		 : SYMBOL_MATCHES_SEARCH_NAME (*top,name)))
+	     && SYMBOL_MATCHES_SEARCH_NAME (*top, name))
 	{
 	  if (symbol_matches_domain (SYMBOL_LANGUAGE (*top),
 				     SYMBOL_DOMAIN (*top), domain))
@@ -1830,15 +1809,9 @@ lookup_partial_symbol (struct partial_sy
       for (psym = start; psym < start + length; psym++)
 	{
 	  if (symbol_matches_domain (SYMBOL_LANGUAGE (*psym),
-				     SYMBOL_DOMAIN (*psym), domain))
-	    {
-	      if (linkage_name != NULL
-		  ? strcmp (SYMBOL_LINKAGE_NAME (*psym), linkage_name) == 0
-		  : SYMBOL_MATCHES_SEARCH_NAME (*psym, name))
-		{
-		  return (*psym);
-		}
-	    }
+				     SYMBOL_DOMAIN (*psym), domain)
+	      && SYMBOL_MATCHES_SEARCH_NAME (*psym, name))
+	    return (*psym);
 	}
     }
 
@@ -1880,7 +1853,7 @@ basic_lookup_transparent_type (const cha
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-    sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
     if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
       {
 	return SYMBOL_TYPE (sym);
@@ -1889,13 +1862,12 @@ basic_lookup_transparent_type (const cha
 
   ALL_PSYMTABS (objfile, ps)
   {
-    if (!ps->readin && lookup_partial_symbol (ps, name, NULL,
-					      1, STRUCT_DOMAIN))
+    if (!ps->readin && lookup_partial_symbol (ps, name, 1, STRUCT_DOMAIN))
       {
 	s = PSYMTAB_TO_SYMTAB (ps);
 	bv = BLOCKVECTOR (s);
 	block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-	sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+	sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
 	if (!sym)
 	  {
 	    /* This shouldn't be necessary, but as a last resort
@@ -1904,7 +1876,7 @@ basic_lookup_transparent_type (const cha
 	     * the psymtab gets it wrong in some cases.
 	     */
 	    block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-	    sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+	    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
 	    if (!sym)
 	      error (_("Internal: global symbol `%s' found in %s psymtab but not in symtab.\n\
 %s may be an inlined function, or may be a template function\n\
@@ -1928,7 +1900,7 @@ basic_lookup_transparent_type (const cha
   {
     bv = BLOCKVECTOR (s);
     block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-    sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
     if (sym && !TYPE_IS_OPAQUE (SYMBOL_TYPE (sym)))
       {
 	return SYMBOL_TYPE (sym);
@@ -1937,12 +1909,12 @@ basic_lookup_transparent_type (const cha
 
   ALL_PSYMTABS (objfile, ps)
   {
-    if (!ps->readin && lookup_partial_symbol (ps, name, NULL, 0, STRUCT_DOMAIN))
+    if (!ps->readin && lookup_partial_symbol (ps, name, 0, STRUCT_DOMAIN))
       {
 	s = PSYMTAB_TO_SYMTAB (ps);
 	bv = BLOCKVECTOR (s);
 	block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
-	sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+	sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
 	if (!sym)
 	  {
 	    /* This shouldn't be necessary, but as a last resort
@@ -1951,7 +1923,7 @@ basic_lookup_transparent_type (const cha
 	     * the psymtab gets it wrong in some cases.
 	     */
 	    block = BLOCKVECTOR_BLOCK (bv, GLOBAL_BLOCK);
-	    sym = lookup_block_symbol (block, name, NULL, STRUCT_DOMAIN);
+	    sym = lookup_block_symbol (block, name, STRUCT_DOMAIN);
 	    if (!sym)
 	      error (_("Internal: static symbol `%s' found in %s psymtab but not in symtab.\n\
 %s may be an inlined function, or may be a template function\n\
@@ -1978,7 +1950,7 @@ find_main_psymtab (void)
 
   ALL_PSYMTABS (objfile, pst)
   {
-    if (lookup_partial_symbol (pst, main_name (), NULL, 1, VAR_DOMAIN))
+    if (lookup_partial_symbol (pst, main_name (), 1, VAR_DOMAIN))
       {
 	return (pst);
       }
@@ -1996,14 +1968,10 @@ find_main_psymtab (void)
    search on the symbols.  Each symbol which is marked as being a ObjC/C++
    symbol (language_cplus or language_objc set) has both the encoded and
    non-encoded names tested for a match.
-
-   If LINKAGE_NAME is non-NULL, verify that any symbol we find has this
-   particular mangled name.
 */
 
 struct symbol *
 lookup_block_symbol (const struct block *block, const char *name,
-		     const char *linkage_name,
 		     const domain_enum domain)
 {
   struct dict_iterator iter;
@@ -2016,9 +1984,7 @@ lookup_block_symbol (const struct block 
 	   sym = dict_iter_name_next (name, &iter))
 	{
 	  if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
-				     SYMBOL_DOMAIN (sym), domain)
-	      && (linkage_name != NULL
-		  ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1))
+				     SYMBOL_DOMAIN (sym), domain))
 	    return sym;
 	}
       return NULL;
@@ -2038,9 +2004,7 @@ lookup_block_symbol (const struct block 
 	   sym = dict_iter_name_next (name, &iter))
 	{
 	  if (symbol_matches_domain (SYMBOL_LANGUAGE (sym),
-				     SYMBOL_DOMAIN (sym), domain)
-	      && (linkage_name != NULL
-		  ? strcmp (SYMBOL_LINKAGE_NAME (sym), linkage_name) == 0 : 1))
+				     SYMBOL_DOMAIN (sym), domain))
 	    {
 	      sym_found = sym;
 	      if (!SYMBOL_IS_ARGUMENT (sym))
Index: symtab.h
===================================================================
RCS file: /cvs/src/src/gdb/symtab.h,v
retrieving revision 1.146
diff -u -p -r1.146 symtab.h
--- symtab.h	27 Jan 2010 00:15:59 -0000	1.146
+++ symtab.h	28 Jan 2010 23:15:50 -0000
@@ -172,9 +172,6 @@ extern CORE_ADDR symbol_overlayed_addres
 #define SYMBOL_SECTION(symbol)		(symbol)->ginfo.section
 #define SYMBOL_OBJ_SECTION(symbol)	(symbol)->ginfo.obj_section
 
-#define SYMBOL_CPLUS_DEMANGLED_NAME(symbol)	\
-  (symbol)->ginfo.language_specific.cplus_specific.demangled_name
-
 /* Initializes the language dependent portion of a symbol
    depending upon the language for the symbol. */
 #define SYMBOL_INIT_LANGUAGE_SPECIFIC(symbol,language) \
@@ -994,7 +991,6 @@ extern struct symbol *lookup_symbol (con
    that can't think of anything better to do.  */
 
 extern struct symbol *basic_lookup_symbol_nonlocal (const char *,
-						    const char *,
 						    const struct block *,
 						    const domain_enum);
 
@@ -1005,7 +1001,6 @@ extern struct symbol *basic_lookup_symbo
    is one; do nothing if BLOCK is NULL or a global block.  */
 
 extern struct symbol *lookup_symbol_static (const char *name,
-					    const char *linkage_name,
 					    const struct block *block,
 					    const domain_enum domain);
 
@@ -1013,7 +1008,6 @@ extern struct symbol *lookup_symbol_stat
    necessary).  */
 
 extern struct symbol *lookup_symbol_global (const char *name,
-					    const char *linkage_name,
 					    const struct block *block,
 					    const domain_enum domain);
 
@@ -1022,21 +1016,18 @@ extern struct symbol *lookup_symbol_glob
    will fix up the symbol if necessary.  */
 
 extern struct symbol *lookup_symbol_aux_block (const char *name,
-					       const char *linkage_name,
 					       const struct block *block,
 					       const domain_enum domain);
 
 /* Lookup a partial symbol.  */
 
 extern struct partial_symbol *lookup_partial_symbol (struct partial_symtab *,
-						     const char *,
 						     const char *, int,
 						     domain_enum);
 
 /* lookup a symbol by name, within a specified block */
 
 extern struct symbol *lookup_block_symbol (const struct block *, const char *,
-					   const char *,
 					   const domain_enum);
 
 /* lookup a [struct, union, enum] by name, within a specified block */
@@ -1372,7 +1363,6 @@ extern /*const */ char *main_name (void)
 /* Check global symbols in objfile.  */
 struct symbol *lookup_global_symbol_from_objfile (const struct objfile *objfile,
 						  const char *name,
-						  const char *linkage_name,
 						  const domain_enum domain);
 
 extern struct symtabs_and_lines
Index: valops.c
===================================================================
RCS file: /cvs/src/src/gdb/valops.c,v
retrieving revision 1.233
diff -u -p -r1.233 valops.c
--- valops.c	26 Jan 2010 16:47:34 -0000	1.233
+++ valops.c	28 Jan 2010 23:15:53 -0000
@@ -3096,7 +3122,7 @@ value_maybe_namespace_elt (const struct 
   struct symbol *sym;
   struct value *result;
 
-  sym = cp_lookup_symbol_namespace (namespace_name, name, NULL,
+  sym = cp_lookup_symbol_namespace(namespace_name, name,
 				    get_selected_block (0), 
 				    VAR_DOMAIN, 1);
 
@@ -3240,7 +3266,7 @@ value_of_local (const char *name, int co
 
   /* Calling lookup_block_symbol is necessary to get the LOC_REGISTER
      symbol instead of the LOC_ARG one (if both exist).  */
-  sym = lookup_block_symbol (b, name, NULL, VAR_DOMAIN);
+  sym = lookup_block_symbol (b, name, VAR_DOMAIN);
   if (sym == NULL)
     {
       if (complain)

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-01-28 23:41                         ` Keith Seitz
@ 2010-02-01 16:48                           ` Daniel Jacobowitz
  2010-02-01 19:32                             ` Keith Seitz
  2010-02-04 17:21                             ` Tom Tromey
  0 siblings, 2 replies; 50+ messages in thread
From: Daniel Jacobowitz @ 2010-02-01 16:48 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

I think we need to get these patches in to make progress; they're too
big, and getting them down to no regressions on one platform is
already a noteworthy accomplishment.  So I'm going to keep comments to
a minimum.

That means you should probably wait to commit this until after GDB 7.1
branches (~ 2 weeks).

On Thu, Jan 28, 2010 at 03:39:51PM -0800, Keith Seitz wrote:
> -/* Determine whether a die of type TAG living in a C++ class or
> -   namespace needs to have the name of the scope prepended to the
> -   name listed in the die.  */
> +/* Determine whether DIE needs to have the name of the scope prepended
> +   to the name listed in the die.  */
>  
>  static int
> -pdi_needs_namespace (enum dwarf_tag tag)
> +die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu)
>  {
> -  switch (tag)
> +  switch (die->tag)
>      {
>      case DW_TAG_namespace:
>      case DW_TAG_typedef:
> @@ -2623,7 +2612,23 @@ pdi_needs_namespace (enum dwarf_tag tag)
>      case DW_TAG_union_type:
>      case DW_TAG_enumeration_type:
>      case DW_TAG_enumerator:
> +    case DW_TAG_subprogram:
> +    case DW_TAG_member:
>        return 1;
> +
> +    case DW_TAG_variable:
> +      {
> +	struct attribute *attr;
> +	attr = dwarf2_attr (die, DW_AT_specification, cu);
> +	if (attr)
> +	  return 1;
> +	attr = dwarf2_attr (die, DW_AT_external, cu);
> +	if (attr == NULL && die->parent->tag != DW_TAG_namespace)
> +	  return 0;
> +	return 1;
> +      }
> +      break;
> +
>      default:
>        return 0;
>      }

What's this about?  It needs an explanation, and I don't think
DW_AT_specification has anything to do with die_needs_namespace.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-01 16:48                           ` Daniel Jacobowitz
@ 2010-02-01 19:32                             ` Keith Seitz
  2010-02-01 19:39                               ` Daniel Jacobowitz
  2010-02-04 17:21                             ` Tom Tromey
  1 sibling, 1 reply; 50+ messages in thread
From: Keith Seitz @ 2010-02-01 19:32 UTC (permalink / raw)
  To: gdb-patches

On 02/01/2010 08:48 AM, Daniel Jacobowitz wrote:
>> +    case DW_TAG_variable:
>> +      {
>> +	struct attribute *attr;
>> +	attr = dwarf2_attr (die, DW_AT_specification, cu);
>> +	if (attr)
>> +	  return 1;
>> +	attr = dwarf2_attr (die, DW_AT_external, cu);
>> +	if (attr == NULL&&  die->parent->tag != DW_TAG_namespace)
>> +	  return 0;
>> +	return 1;
>> +      }
>> +      break;
>> +
>>       default:
>>         return 0;
>>       }
>
> What's this about?  It needs an explanation, and I don't think
> DW_AT_specification has anything to do with die_needs_namespace.

DW_AT_specification is, as I deduce from ifdefing that out and running 
the testsuite :-), needed for many namespace-based variables:

*************** PASS: gdb.cp/namespace.exp: ptype OtherF
*** 12145,12159 ****
   KFAIL: gdb.cp/namespace.exp: ptype ::C::OtherFileClass (PRMS: gdb/1448)
   PASS: gdb.cp/namespace.exp: ptype C::OtherFileClass
   PASS: gdb.cp/namespace.exp: print cX
! PASS: gdb.cp/namespace.exp: print 'F::cXf'
! PASS: gdb.cp/namespace.exp: print F::cXf
! PASS: gdb.cp/namespace.exp: print F::cXfX
   PASS: gdb.cp/namespace.exp: print X
! PASS: gdb.cp/namespace.exp: print 'G::Xg'
! PASS: gdb.cp/namespace.exp: print G::Xg
! PASS: gdb.cp/namespace.exp: print G::XgX
! PASS: gdb.cp/namespace.exp: print cXOtherFile
! PASS: gdb.cp/namespace.exp: print XOtherFile
   PASS: gdb.cp/namespace.exp: print AAA::ALPHA
   Running ../../../src/gdb/testsuite/gdb.cp/namespace-nested-import.exp ...
   PASS: gdb.cp/namespace-nested-import.exp: print C::x
--- 12145,12159 ----
   KFAIL: gdb.cp/namespace.exp: ptype ::C::OtherFileClass (PRMS: gdb/1448)
   PASS: gdb.cp/namespace.exp: ptype C::OtherFileClass
   PASS: gdb.cp/namespace.exp: print cX
! FAIL: gdb.cp/namespace.exp: print 'F::cXf'
! FAIL: gdb.cp/namespace.exp: print F::cXf
! FAIL: gdb.cp/namespace.exp: print F::cXfX
   PASS: gdb.cp/namespace.exp: print X
! FAIL: gdb.cp/namespace.exp: print 'G::Xg'
! FAIL: gdb.cp/namespace.exp: print G::Xg
! FAIL: gdb.cp/namespace.exp: print G::XgX
! FAIL: gdb.cp/namespace.exp: print cXOtherFile
! FAIL: gdb.cp/namespace.exp: print XOtherFile
   PASS: gdb.cp/namespace.exp: print AAA::ALPHA
   Running ../../../src/gdb/testsuite/gdb.cp/namespace-nested-import.exp ...
   PASS: gdb.cp/namespace-nested-import.exp: print C::x

I apologize, it has been quite some time since this was written, and 
I've forgotten much of the context. So commenting out the code and 
re-running the test suite is the best I can do to remember why some 
things were done.

Was there something else in particular that was unclear?
Keith

PS. Tom also has a patch on expr-cumulative in this spot that deals with 
static variables defined inside a block.


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-01 19:32                             ` Keith Seitz
@ 2010-02-01 19:39                               ` Daniel Jacobowitz
  2010-02-01 21:52                                 ` Keith Seitz
  0 siblings, 1 reply; 50+ messages in thread
From: Daniel Jacobowitz @ 2010-02-01 19:39 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Mon, Feb 01, 2010 at 11:32:08AM -0800, Keith Seitz wrote:
> On 02/01/2010 08:48 AM, Daniel Jacobowitz wrote:
> >>+    case DW_TAG_variable:
> >>+      {
> >>+	struct attribute *attr;
> >>+	attr = dwarf2_attr (die, DW_AT_specification, cu);
> >>+	if (attr)
> >>+	  return 1;
> >>+	attr = dwarf2_attr (die, DW_AT_external, cu);
> >>+	if (attr == NULL&&  die->parent->tag != DW_TAG_namespace)
> >>+	  return 0;
> >>+	return 1;
> >>+      }
> >>+      break;
> >>+
> >>      default:
> >>        return 0;
> >>      }
> >
> >What's this about?  It needs an explanation, and I don't think
> >DW_AT_specification has anything to do with die_needs_namespace.
> 
> DW_AT_specification is, as I deduce from ifdefing that out and
> running the testsuite :-), needed for many namespace-based variables:

DW_AT_specification is present for many variables in namespaces
(at least in current GCC output).  But what significance does it
actually have?  Can you explain the check above in terms of the DWARF
standard?  If not, I don't think it's right.

DW_AT_specification just says that there is a specification of this
variable in another DIE.  The same variable could be written with
or without it.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-01 19:39                               ` Daniel Jacobowitz
@ 2010-02-01 21:52                                 ` Keith Seitz
  2010-02-01 22:19                                   ` Daniel Jacobowitz
  0 siblings, 1 reply; 50+ messages in thread
From: Keith Seitz @ 2010-02-01 21:52 UTC (permalink / raw)
  To: gdb-patches

On 02/01/2010 11:39 AM, Daniel Jacobowitz wrote:
> DW_AT_specification is present for many variables in namespaces
> (at least in current GCC output).  But what significance does it
> actually have?  Can you explain the check above in terms of the DWARF
> standard?  If not, I don't think it's right.

I don't know if what gcc is doing is proper DWARF or not, but I don't 
see any indication on reading the DWARF3 spec that it is.

If I may use namespace.exp as an example:

namespace
{
   namespace G
   {
     int Xg;
   };
};

For this code, gcc will output a type-like information DIE tree, telling 
us ONLY about the composition of the anonymous namespace with namespace 
G and variable Xg. Later gcc gives us a DIE with DW_AT_location (to 
continue my (poor) type analogy: an instance of the variable). To 
describe this DIE, we also get DW_AT_specification and nothing more. 
Just DW_AT_location and DW_AT_specification.

If we do not follow DW_AT_specification, dwarf2_physname will put the 
variable Xg in the global namespace instead of "(anonymous 
namespace)::G::Xg", which is where it really is defined.

> DW_AT_specification just says that there is a specification of this
> variable in another DIE.  The same variable could be written with
> or without it.

In the case where DW_AT_specification is omitted, the physname 
information is contained within the DIE's immediate ancestry. I would 
expect to see, e.g.,

DW_TAG_namespace
-- DW_AT_name
-- DW_TAG_namespace
    -- DW_AT_name
    -- DW_TAG_variable
       -- DW_AT_name
       -- DW_AT_location

as opposed to (the below is what we actually get from gcc)

DW_TAG_namespace
-- DW_AT_name
-- DW_TAG_namespace
    -- DW_AT_name
    -- DW_TAG_variable
       -- DW_AT_name
...
DW_AT_variable
-- DW_AT_specification (points to DW_TAG_variable above)
-- DW_AT_location

Keith


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-01 21:52                                 ` Keith Seitz
@ 2010-02-01 22:19                                   ` Daniel Jacobowitz
  2010-02-02 23:23                                     ` Keith Seitz
  0 siblings, 1 reply; 50+ messages in thread
From: Daniel Jacobowitz @ 2010-02-01 22:19 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Mon, Feb 01, 2010 at 01:52:27PM -0800, Keith Seitz wrote:
> For this code, gcc will output a type-like information DIE tree,
> telling us ONLY about the composition of the anonymous namespace with
> namespace G and variable Xg. Later gcc gives us a DIE with
> DW_AT_location (to continue my (poor) type analogy: an instance of
> the variable). To describe this DIE, we also get DW_AT_specification
> and nothing more. Just DW_AT_location and DW_AT_specification.
> 
> If we do not follow DW_AT_specification, dwarf2_physname will put the
> variable Xg in the global namespace instead of "(anonymous
> namespace)::G::Xg", which is where it really is defined.

Right.  The issue is not the presence or absence of the
DW_AT_specification; the issue is whether to follow this DIE's
parents, or its specification's parents.  The reader handles this in a
couple of other places already.  For instance, see the comment in
determine_prefix.

I think this code has evolved a couple of times since the referenced
block was added.  Certainly all callers of the old pdi_needs_namespace
are removed; the callers of die_needs_namespace are new.  It may
no longer be right.

What're we trying to answer?  For instance, is it the distinction
between local variables and global variables?  This is interesting
because I believe that function-local classes get the enclosing
function as a prefix, but obviously function-local automatic variables
should not.

Judging from some examples, you can not distinguish function local and
function static variables without decoding DW_AT_location.  But that's
not the most important case; we don't need to qualify function local
variables in the symbol table and things will work out OK.

I'm not sure how DW_TAG_member comes into this either, that doesn't
entirely make sense for non-static class members.  Be careful about
this one: GCC sometimes incorrectly uses DW_TAG_variable, when the
DWARF standard says they should be DW_TAG_member.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-01 22:19                                   ` Daniel Jacobowitz
@ 2010-02-02 23:23                                     ` Keith Seitz
  2010-02-02 23:31                                       ` Keith Seitz
  2010-02-03  2:46                                       ` Daniel Jacobowitz
  0 siblings, 2 replies; 50+ messages in thread
From: Keith Seitz @ 2010-02-02 23:23 UTC (permalink / raw)
  To: gdb-patches

On 02/01/2010 02:19 PM, Daniel Jacobowitz wrote:

> What're we trying to answer?  For instance, is it the distinction
> between local variables and global variables?  This is interesting
> because I believe that function-local classes get the enclosing
> function as a prefix, but obviously function-local automatic variables
> should not.

Yes, it was specifically to deal with class static members. Reminder:

namespace
{
   namespace G
   {
     int Gx;
   };
};

gcc will output:
DW_TAG_namespace
-- DW_TAG_namespace
-- DW_AT_name = "G"
---- DW_TAG_variable
---- DW_AT_name = "Gx"

DW_TAG_variable
-- DW_AT_location
-- DW_AT_specification = DW_TAG_variable above

This seems to be correct as far as my interpretation of the DWARF3 spec 
(Dec 20, 2005), Section 4.1 #6 (pg 60).

> I'm not sure how DW_TAG_member comes into this either, that doesn't
> entirely make sense for non-static class members.  Be careful about
> this one: GCC sometimes incorrectly uses DW_TAG_variable, when the
> DWARF standard says they should be DW_TAG_member.

DW_TAG_member does not run through this branch, unless, as you say, gcc 
incorrectly emits DW_TAG_variable instead of DW_TAG_member. I have only 
seen gcc output DW_TAG_variable for member data in two situations: 1) 
static class members (which I think is correct) and 2) const class 
members where the class is not instantiated.

To elaborate on #2:

Consider the following class:

class A
{
public:
  static const int a_constant = 3;
};

int
main (int argc, char* argv[])
{
   return A::a_constant;
}

Gcc will *NOT* output anything about A::a_constant *except* for a 
DW_TAG_variable describing it (DW_AT_name = "a_constant"). No 
DW_AT_specification (as I think there should be). In fact, 
DW_TAG_class_type for A is completely omitted. The only clue that gdb 
gets (either dwarf2_physname or CVS HEAD) is in DW_AT_MIPS_linkage_name. 
This is obviously a gcc bug.

Do you have another example where gcc does this that you'd like me to 
look at?

Or maybe I'm simply not answering your question? [A kind of forest/tree 
thing...]

Keith


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-02 23:23                                     ` Keith Seitz
@ 2010-02-02 23:31                                       ` Keith Seitz
  2010-02-03  2:46                                       ` Daniel Jacobowitz
  1 sibling, 0 replies; 50+ messages in thread
From: Keith Seitz @ 2010-02-02 23:31 UTC (permalink / raw)
  To: gdb-patches

On 02/02/2010 03:23 PM, Keith Seitz wrote:

> Yes, it was specifically to deal with class static members. Reminder:

<cough>

Class static members *and* globals in namespaces...

:-)

Keith


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-02 23:23                                     ` Keith Seitz
  2010-02-02 23:31                                       ` Keith Seitz
@ 2010-02-03  2:46                                       ` Daniel Jacobowitz
  2010-02-04 17:48                                         ` Tom Tromey
  1 sibling, 1 reply; 50+ messages in thread
From: Daniel Jacobowitz @ 2010-02-03  2:46 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Tue, Feb 02, 2010 at 03:23:44PM -0800, Keith Seitz wrote:
> To elaborate on #2:
> 
> Consider the following class:
> 
> class A
> {
> public:
>  static const int a_constant = 3;
> };
> 
> int
> main (int argc, char* argv[])
> {
>   return A::a_constant;
> }
> 
> Gcc will *NOT* output anything about A::a_constant *except* for a
> DW_TAG_variable describing it (DW_AT_name = "a_constant"). No
> DW_AT_specification (as I think there should be). In fact,
> DW_TAG_class_type for A is completely omitted. The only clue that gdb
> gets (either dwarf2_physname or CVS HEAD) is in
> DW_AT_MIPS_linkage_name. This is obviously a gcc bug.

It's not obvious that it's a bug.  I believe you need to declare the
constant again, outside of the class, for it to be really 'defined'.
This trips people up all the time.  (Including me, so don't trust me
too much.)  e.g. it won't have the correct external linkage it's
supposed to have.

> Or maybe I'm simply not answering your question? [A kind of
> forest/tree thing...]

You're right, we're talking past each other.

I don't doubt that what you've got is correctly identifying and
handling GCC's output.  But it does so by pattern matching on what GCC
currently emits, not by using tests that are sound according to the
standard.  So with some future GCC, or some other non-GCC compiler,
it will probably fall down.

I don't believe that most of GCC's uses of DW_AT_specification are
required by the standard.  And I don't think they're the only valid
uses of DW_AT_specification.  So keying off whether that attribute is
present is too 'fuzzy' for me.

I'm asking for you to either convince me that my assumptions in the
previous paragraph are incorrect, or to find some way that the
standard will support to answer the same query about the properties of
the DW_TAG_variable DIE.  For instance, should we find the DIE's
logical location the same way determine_prefix does (parent, or
specification's parent) and then draw some conclusion based on
the type of the logical parent?

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-01 16:48                           ` Daniel Jacobowitz
  2010-02-01 19:32                             ` Keith Seitz
@ 2010-02-04 17:21                             ` Tom Tromey
  2010-02-04 17:25                               ` Daniel Jacobowitz
  1 sibling, 1 reply; 50+ messages in thread
From: Tom Tromey @ 2010-02-04 17:21 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

>>>>> "Daniel" == Daniel Jacobowitz <dan@codesourcery.com> writes:

>> +die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu)
>> {
[...]
>> +    case DW_TAG_variable:
>> +      {
>> +	struct attribute *attr;
>> +	attr = dwarf2_attr (die, DW_AT_specification, cu);
>> +	if (attr)
>> +	  return 1;
>> +	attr = dwarf2_attr (die, DW_AT_external, cu);
>> +	if (attr == NULL && die->parent->tag != DW_TAG_namespace)
>> +	  return 0;
>> +	return 1;

Daniel> What's this about?  It needs an explanation, and I don't think
Daniel> DW_AT_specification has anything to do with die_needs_namespace.

I read through this sub-thread a little, and looked at the DWARF spec
too.

Here is what I believe to be the relevant text from the spec:

    If a type, variable, or function declared in a namespace is defined
    outside of the body of the namespace declaration, that type, variable,
    or function definition entry has a DW_AT_specification attribute whose
    value is a reference to the debugging information entry representing the
    declaration of the type, variable or function. Type, variable, or
    function entries with a DW_AT_specification attribute do not need to
    duplicate information provided by the declaration entry referenced by
    the specification attribute.

So, if a DIE has a DW_AT_specification, then we must use the namespace
indicated by the referenced DIE.  If it does not have DW_AT_specification,
then we use its own parentage.

It is not clear to me whether it is possible for a DIE to have a
DW_AT_specification referring to another DIE which is not in a
namespace.  Offhand this seems invalid, but if it does occur, it could
be supported in this function with just a little more effort.

I don't understand why die_needs_namespace only does this for
DW_TAG_variable and not other things.  I also don't understand why it
unconditionally returns 1 for enumerators, functions, and the like.
However, I didn't look to see how it is used, so perhaps it doesn't
matter.

After reading more of the thread, maybe I am missing the point.

Tom


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-04 17:21                             ` Tom Tromey
@ 2010-02-04 17:25                               ` Daniel Jacobowitz
  0 siblings, 0 replies; 50+ messages in thread
From: Daniel Jacobowitz @ 2010-02-04 17:25 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Keith Seitz, gdb-patches

On Thu, Feb 04, 2010 at 10:21:44AM -0700, Tom Tromey wrote:
> I don't understand why die_needs_namespace only does this for
> DW_TAG_variable and not other things.  I also don't understand why it
> unconditionally returns 1 for enumerators, functions, and the like.
> However, I didn't look to see how it is used, so perhaps it doesn't
> matter.

I think it's because we need to distinguish local and global
variables.  Enumerators don't have this problem (I'm not sure about
members).

As for local functions, I have no idea...

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-03  2:46                                       ` Daniel Jacobowitz
@ 2010-02-04 17:48                                         ` Tom Tromey
  2010-02-04 18:14                                           ` Daniel Jacobowitz
  0 siblings, 1 reply; 50+ messages in thread
From: Tom Tromey @ 2010-02-04 17:48 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

>>>>> "Daniel" == Daniel Jacobowitz <dan@codesourcery.com> writes:

Daniel> I don't doubt that what you've got is correctly identifying and
Daniel> handling GCC's output.  But it does so by pattern matching on what GCC
Daniel> currently emits, not by using tests that are sound according to the
Daniel> standard.  So with some future GCC, or some other non-GCC compiler,
Daniel> it will probably fall down.

Daniel> I don't believe that most of GCC's uses of DW_AT_specification are
Daniel> required by the standard.  And I don't think they're the only valid
Daniel> uses of DW_AT_specification.  So keying off whether that attribute is
Daniel> present is too 'fuzzy' for me.

I want to tie this back to the original code to see if I understand what
part you are concerned about.

>> +    case DW_TAG_variable:
>> +      {
>> +	struct attribute *attr;
>> +	attr = dwarf2_attr (die, DW_AT_specification, cu);
>> +	if (attr)
>> +	  return 1;

Based on the above I am guessing it is the early return here?

That is the only thing I could think of, because AFAICT this code
generally respects what DWARF says.  My understanding is that there are
2 cases.

1. If the variable is declared in the namespace scope, but defined
outside, then a second defining DIE is emitted that refers to the
declaration DIE using DW_AT_specification.  In this case the declaration
DIE's namespace is used.

... The code above seems to cheat a tiny bit because it unconditionally
returns 1 in this case, whereas it should perhaps recurse.

2. If the variable is defined in the namespace scope, then no
DW_AT_specification exists, and we use the DIE's parentage.  The code
gets this right.

Daniel> I'm asking for you to either convince me that my assumptions in the
Daniel> previous paragraph are incorrect, or to find some way that the
Daniel> standard will support to answer the same query about the properties of
Daniel> the DW_TAG_variable DIE.  For instance, should we find the DIE's
Daniel> logical location the same way determine_prefix does (parent, or
Daniel> specification's parent) and then draw some conclusion based on
Daniel> the type of the logical parent?

From what I can tell, die_needs_namespace is consistent with
determine_prefix, with the caveat that it is is an approximation, due to
the lack of recursion.  It is more like "die_may_need_namespace".

I'm still not understanding what problem you see, but I would like to.

Tom


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-04 17:48                                         ` Tom Tromey
@ 2010-02-04 18:14                                           ` Daniel Jacobowitz
  2010-02-05 17:13                                             ` Keith Seitz
  0 siblings, 1 reply; 50+ messages in thread
From: Daniel Jacobowitz @ 2010-02-04 18:14 UTC (permalink / raw)
  To: Tom Tromey; +Cc: Keith Seitz, gdb-patches

On Thu, Feb 04, 2010 at 10:48:13AM -0700, Tom Tromey wrote:
> >> +    case DW_TAG_variable:
> >> +      {
> >> +	struct attribute *attr;
> >> +	attr = dwarf2_attr (die, DW_AT_specification, cu);
> >> +	if (attr)
> >> +	  return 1;
> 
> Based on the above I am guessing it is the early return here?

That's part of it.  Also, I don't think the check for DW_AT_external
tests what we want (which is what I'm trying to pin down - what is the
desired property?).

Check the debug info for this:

namespace X
{
  int xx;
  static int yy;
}

xx is DW_AT_external, yy isn't.

> 1. If the variable is declared in the namespace scope, but defined
> outside, then a second defining DIE is emitted that refers to the
> declaration DIE using DW_AT_specification.  In this case the declaration
> DIE's namespace is used.
> 
> ... The code above seems to cheat a tiny bit because it unconditionally
> returns 1 in this case, whereas it should perhaps recurse.

Recursing's a good idea.  I hadn't thought of that.

> I'm still not understanding what problem you see, but I would like to.

I really, really want a specification for this function that describes
what it's trying to accomplish.  I don't understand what it's for, so
it's hard to translate my red flags into suggestions.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-04 18:14                                           ` Daniel Jacobowitz
@ 2010-02-05 17:13                                             ` Keith Seitz
  2010-02-05 17:29                                               ` Daniel Jacobowitz
  0 siblings, 1 reply; 50+ messages in thread
From: Keith Seitz @ 2010-02-05 17:13 UTC (permalink / raw)
  To: gdb-patches

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

On 02/04/2010 10:14 AM, Daniel Jacobowitz wrote:

> That's part of it.  Also, I don't think the check for DW_AT_external
> tests what we want (which is what I'm trying to pin down - what is the
> desired property?).

Yes, we are trying to ascertain whether the DIE (a DW_TAG_variable) in 
question needs to be prefixed -- same job it used to do AFAICT. The 
difference is that it is now being used for a much more complex job, 
which requires us to refine the behavior of pdi_needs_namespace for more 
inputs. In particular, it is the use of dwarf2_physname in new_symbol 
which necessitates this change.

Previously, this code (pdi_needs_namespace) unconditionally returned 1 
(for this DW_TAG_variable case), which is not unilaterally correct anymore.

>> 1. If the variable is declared in the namespace scope, but defined
>> outside, then a second defining DIE is emitted that refers to the
>> declaration DIE using DW_AT_specification.  In this case the declaration
>> DIE's namespace is used.
>>
>> ... The code above seems to cheat a tiny bit because it unconditionally
>> returns 1 in this case, whereas it should perhaps recurse.
>
> Recursing's a good idea.  I hadn't thought of that.

I hadn't either. Next iteration in attached patch.

BTW, while goofing around with the code a bit, it appears that since I 
wrote all of this many, many months ago, things have changed (for the 
better). physname_prefix and dependents are no longer necessary. We can 
use determine_prefix instead. I apologize that I did not catch this earlier.

Since dwarf2_full_name and dwarf2_physname are almost identical, I've 
also merged the two functions.

I've also added a NAME parameter so that callers can pass in the result 
of a previous dwarf2_name call. I noticed quite some time ago that this 
method was being called several times in a row.

I've appended an updated patch of dwarf2read.c with CVS HEAD.

Keith

[-- Attachment #2: physname-dwarf2read.c-revised.patch --]
[-- Type: text/plain, Size: 16967 bytes --]

Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.352
diff -u -p -r1.352 dwarf2read.c
--- dwarf2read.c	26 Jan 2010 15:48:25 -0000	1.352
+++ dwarf2read.c	5 Feb 2010 17:03:36 -0000
@@ -48,6 +48,8 @@
 #include "gdbcmd.h"
 #include "block.h"
 #include "addrmap.h"
+#include "typeprint.h"
+#include "jv-lang.h"
 
 #include <fcntl.h>
 #include "gdb_string.h"
@@ -487,8 +489,7 @@ struct partial_die_info
     unsigned int has_byte_size : 1;
 
     /* The name of this DIE.  Normally the value of DW_AT_name, but
-       sometimes DW_TAG_MIPS_linkage_name or a string computed in some
-       other fashion.  */
+       sometimes a default name for unnamed DIEs.  */
     char *name;
 
     /* The scope to prepend to our children.  This is generally
@@ -788,8 +789,6 @@ static void scan_partial_symbols (struct
 static void add_partial_symbol (struct partial_die_info *,
 				struct dwarf2_cu *);
 
-static int pdi_needs_namespace (enum dwarf_tag tag);
-
 static void add_partial_namespace (struct partial_die_info *pdi,
 				   CORE_ADDR *lowpc, CORE_ADDR *highpc,
 				   int need_pc, struct dwarf2_cu *cu);
@@ -984,9 +983,6 @@ static void dwarf2_attach_fn_fields_to_t
 
 static void process_structure_scope (struct die_info *, struct dwarf2_cu *);
 
-static const char *determine_class_name (struct die_info *die,
-					 struct dwarf2_cu *cu);
-
 static void read_common_block (struct die_info *, struct dwarf2_cu *);
 
 static void read_namespace (struct die_info *die, struct dwarf2_cu *);
@@ -1028,8 +1024,6 @@ static gdb_byte *read_full_die (const st
 
 static void process_die (struct die_info *, struct dwarf2_cu *);
 
-static char *dwarf2_linkage_name (struct die_info *, struct dwarf2_cu *);
-
 static char *dwarf2_canonicalize_name (char *, struct dwarf2_cu *,
 				       struct obstack *);
 
@@ -2441,12 +2435,9 @@ add_partial_symbol (struct partial_die_i
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  if (pdi_needs_namespace (pdi->tag))
-    {
-      actual_name = partial_die_full_name (pdi, cu);
-      if (actual_name)
-	built_actual_name = 1;
-    }
+  actual_name = partial_die_full_name (pdi, cu);
+  if (actual_name)
+    built_actual_name = 1;
 
   if (actual_name == NULL)
     actual_name = pdi->name;
@@ -2586,49 +2577,10 @@ add_partial_symbol (struct partial_die_i
       break;
     }
 
-  /* Check to see if we should scan the name for possible namespace
-     info.  Only do this if this is C++, if we don't have namespace
-     debugging info in the file, if the psym is of an appropriate type
-     (otherwise we'll have psym == NULL), and if we actually had a
-     mangled name to begin with.  */
-
-  /* FIXME drow/2004-02-22: Why don't we do this for classes, i.e. the
-     cases which do not set PSYM above?  */
-
-  if (cu->language == language_cplus
-      && cu->has_namespace_info == 0
-      && psym != NULL
-      && SYMBOL_CPLUS_DEMANGLED_NAME (psym) != NULL)
-    cp_check_possible_namespace_symbols (SYMBOL_CPLUS_DEMANGLED_NAME (psym),
-					 objfile);
-
   if (built_actual_name)
     xfree (actual_name);
 }
 
-/* Determine whether a die of type TAG living in a C++ class or
-   namespace needs to have the name of the scope prepended to the
-   name listed in the die.  */
-
-static int
-pdi_needs_namespace (enum dwarf_tag tag)
-{
-  switch (tag)
-    {
-    case DW_TAG_namespace:
-    case DW_TAG_typedef:
-    case DW_TAG_class_type:
-    case DW_TAG_interface_type:
-    case DW_TAG_structure_type:
-    case DW_TAG_union_type:
-    case DW_TAG_enumeration_type:
-    case DW_TAG_enumerator:
-      return 1;
-    default:
-      return 0;
-    }
-}
-
 /* Read a partial die corresponding to a namespace; also, add a symbol
    corresponding to that namespace to the symbol table.  NAMESPACE is
    the name of the enclosing namespace.  */
@@ -2739,7 +2691,6 @@ guess_structure_name (struct partial_die
 	 could fix this by only using the demangled name to get the
 	 prefix (but see comment in read_structure_type).  */
 
-      struct partial_die_info *child_pdi = struct_pdi->die_child;
       struct partial_die_info *real_pdi;
 
       /* If this DIE (this DIE's specification, if any) has a parent, then
@@ -2752,27 +2703,6 @@ guess_structure_name (struct partial_die
 
       if (real_pdi->die_parent != NULL)
 	return;
-
-      while (child_pdi != NULL)
-	{
-	  if (child_pdi->tag == DW_TAG_subprogram)
-	    {
-	      char *actual_class_name
-		= language_class_name_from_physname (cu->language_defn,
-						     child_pdi->name);
-	      if (actual_class_name != NULL)
-		{
-		  struct_pdi->name
-		    = obsavestring (actual_class_name,
-				    strlen (actual_class_name),
-				    &cu->comp_unit_obstack);
-		  xfree (actual_class_name);
-		}
-	      break;
-	    }
-
-	  child_pdi = child_pdi->die_sibling;
-	}
     }
 }
 
@@ -3337,42 +3267,147 @@ process_die (struct die_info *die, struc
     }
 }
 
+/* A helper function for dwarf2_compute_name which determines whether DIE
+   needs to have the name of the scope prepended to the name listed in the
+   die.  */
+
+static int
+die_needs_namespace (struct die_info *die, struct dwarf2_cu *cu)
+{
+  switch (die->tag)
+    {
+    case DW_TAG_namespace:
+    case DW_TAG_typedef:
+    case DW_TAG_class_type:
+    case DW_TAG_interface_type:
+    case DW_TAG_structure_type:
+    case DW_TAG_union_type:
+    case DW_TAG_enumeration_type:
+    case DW_TAG_enumerator:
+    case DW_TAG_subprogram:
+    case DW_TAG_member:
+      return 1;
+
+    case DW_TAG_variable:
+      if (dwarf2_attr (die, DW_AT_specification, cu))
+	{
+	  struct dwarf2_cu *spec_cu = cu;
+	  return die_needs_namespace (die_specification (die, &spec_cu),
+				      spec_cu);
+	}
+
+      return die_needs_namespace (die->parent, cu);
+
+    default:
+      return 0;
+    }
+}
+
+/* Compute the fully qualified name of DIE in CU.  If PHYSNAME is nonzero,
+   compute the physname for the object, which include a method's
+   formal parameters (C++/Java) and return type (Java).
+
+   The result is allocated on the objfile_obstack and canonicalized.  */
+
+static const char *
+dwarf2_compute_name (char *name, struct die_info *die, struct dwarf2_cu *cu,
+		     int physname)
+{
+  if (name == NULL)
+    name = dwarf2_name (die, cu);
+
+  /* These are the only languages we know how to qualify names in.  */
+  if (name != NULL
+      && (cu->language == language_cplus || cu->language == language_java))
+    {
+      if (die_needs_namespace (die, cu))
+	{
+	  long length;
+	  char *prefix;
+	  struct ui_file *buf;
+
+	  prefix = determine_prefix (die, cu);
+	  buf = mem_fileopen ();
+	  if (*prefix != '\0')
+	    {
+	      char *prefixed_name = typename_concat (NULL, prefix, name, cu);
+	      fputs_unfiltered (prefixed_name, buf);
+	      xfree (prefixed_name);
+	    }
+	  else
+	    fputs_unfiltered (name ? name : "", buf);
+
+	  /* For Java and C++ methods, append formal parameter type
+	     information, if PHYSNAME.  */
+	  
+	  if (physname && die->tag == DW_TAG_subprogram
+	      && (cu->language == language_cplus
+		  || cu->language == language_java))
+	    {
+	      struct type *type = read_type_die (die, cu);
+
+	      c_type_print_args (type, buf, 0, cu->language);
+
+	      if (cu->language == language_java)
+		{
+		  /* For java, we must append the return type to method
+		     names. */
+		  if (die->tag == DW_TAG_subprogram)
+		    java_print_type (TYPE_TARGET_TYPE (type), "", buf,
+				     0, 0);
+		}
+	      else if (cu->language == language_cplus)
+		{
+		  if (TYPE_NFIELDS (type) > 0
+		      && TYPE_FIELD_ARTIFICIAL (type, 0)
+		      && TYPE_CONST (TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (type, 0))))
+		    fputs_unfiltered (" const", buf);
+		}
+	    }
+
+	  name = ui_file_obsavestring (buf, &cu->objfile->objfile_obstack,
+				       &length);
+	  ui_file_delete (buf);
+
+	  if (cu->language == language_cplus)
+	    {
+	      char *cname
+		= dwarf2_canonicalize_name (name, cu,
+					    &cu->objfile->objfile_obstack);
+	      if (cname != NULL)
+		name = cname;
+	    }
+	}
+    }
+
+  return name;
+}
+
 /* Return the fully qualified name of DIE, based on its DW_AT_name.
    If scope qualifiers are appropriate they will be added.  The result
    will be allocated on the objfile_obstack, or NULL if the DIE does
-   not have a name.  */
+   not have a name.  NAME may either be from a previous call to
+   dwarf2_name or NULL.
+
+   The output string will be canonicalized (if C++/Java). */
 
 static const char *
-dwarf2_full_name (struct die_info *die, struct dwarf2_cu *cu)
+dwarf2_full_name (char *name, struct die_info *die, struct dwarf2_cu *cu)
 {
-  struct attribute *attr;
-  char *prefix, *name;
-  struct ui_file *buf = NULL;
+  return dwarf2_compute_name (name, die, cu, 0);
+}
 
-  name = dwarf2_name (die, cu);
-  if (!name)
-    return NULL;
+/* Construct a physname for the given DIE in CU.  NAME may either be
+   from a previous call to dwarf2_name or NULL.  The result will be
+   allocated on teh objfile_objstack or NULL if the DIE does not have a
+   name.
 
-  /* These are the only languages we know how to qualify names in.  */
-  if (cu->language != language_cplus
-      && cu->language != language_java)
-    return name;
+   The output string will be canonicalized (if C++/Java).  */
 
-  /* If no prefix is necessary for this type of DIE, return the
-     unqualified name.  The other three tags listed could be handled
-     in pdi_needs_namespace, but that requires broader changes.  */
-  if (!pdi_needs_namespace (die->tag)
-      && die->tag != DW_TAG_subprogram
-      && die->tag != DW_TAG_variable
-      && die->tag != DW_TAG_member)
-    return name;
-
-  prefix = determine_prefix (die, cu);
-  if (*prefix != '\0')
-    name = typename_concat (&cu->objfile->objfile_obstack, prefix,
-			    name, cu);
-
-  return name;
+static const char *
+dwarf2_physname (char *name, struct die_info *die, struct dwarf2_cu *cu)
+{
+  return dwarf2_compute_name (name, die, cu, 1);
 }
 
 /* Read the import statement specified by the given die and record it.  */
@@ -3843,7 +3878,7 @@ read_func_scope (struct die_info *die, s
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  name = dwarf2_linkage_name (die, cu);
+  name = dwarf2_name (die, cu);
 
   /* Ignore functions with missing or empty names and functions with
      missing or invalid low and high pc attributes.  */
@@ -4517,7 +4552,7 @@ dwarf2_add_field (struct field_info *fip
 	return;
 
       /* Get physical name.  */
-      physname = dwarf2_linkage_name (die, cu);
+      physname = (char *) dwarf2_physname (fieldname, die, cu);
 
       /* The name is already allocated along with this objfile, so we don't
 	 need to duplicate it for the type.  */
@@ -4679,7 +4714,7 @@ dwarf2_add_member_fn (struct field_info 
     return;
 
   /* Get the mangled name.  */
-  physname = dwarf2_linkage_name (die, cu);
+  physname = (char *) dwarf2_physname (fieldname, die, cu);
 
   /* Look up member function name in fieldlist.  */
   for (i = 0; i < fip->nfnfields; i++)
@@ -4986,14 +5021,18 @@ read_structure_type (struct die_info *di
       if (cu->language == language_cplus
 	  || cu->language == language_java)
 	{
-	  const char *new_prefix = determine_class_name (die, cu);
-	  TYPE_TAG_NAME (type) = (char *) new_prefix;
+	  TYPE_TAG_NAME (type) = (char *) dwarf2_full_name (name, die, cu);
+	  if (die->tag == DW_TAG_structure_type
+	      || die->tag == DW_TAG_class_type)
+	    TYPE_NAME (type) = TYPE_TAG_NAME (type);
 	}
       else
 	{
 	  /* The name is already allocated along with this objfile, so
 	     we don't need to duplicate it for the type.  */
-	  TYPE_TAG_NAME (type) = name;
+	  TYPE_TAG_NAME (type) = (char *) name;
+	  if (die->tag == DW_TAG_class_type)
+	    TYPE_NAME (type) = TYPE_TAG_NAME (type);
 	}
     }
 
@@ -5211,7 +5250,7 @@ read_enumeration_type (struct die_info *
   type = alloc_type (objfile);
 
   TYPE_CODE (type) = TYPE_CODE_ENUM;
-  name = dwarf2_full_name (die, cu);
+  name = dwarf2_full_name (NULL, die, cu);
   if (name != NULL)
     TYPE_TAG_NAME (type) = (char *) name;
 
@@ -5236,51 +5275,6 @@ read_enumeration_type (struct die_info *
   return set_die_type (die, type, cu);
 }
 
-/* Determine the name of the type represented by DIE, which should be
-   a named C++ or Java compound type.  Return the name in question,
-   allocated on the objfile obstack.  */
-
-static const char *
-determine_class_name (struct die_info *die, struct dwarf2_cu *cu)
-{
-  const char *new_prefix = NULL;
-
-  /* If we don't have namespace debug info, guess the name by trying
-     to demangle the names of members, just like we did in
-     guess_structure_name.  */
-  if (!processing_has_namespace_info)
-    {
-      struct die_info *child;
-
-      for (child = die->child;
-	   child != NULL && child->tag != 0;
-	   child = sibling_die (child))
-	{
-	  if (child->tag == DW_TAG_subprogram)
-	    {
-	      char *phys_prefix
-		= language_class_name_from_physname (cu->language_defn,
-						     dwarf2_linkage_name
-						     (child, cu));
-
-	      if (phys_prefix != NULL)
-		{
-		  new_prefix
-		    = obsavestring (phys_prefix, strlen (phys_prefix),
-				    &cu->objfile->objfile_obstack);
-		  xfree (phys_prefix);
-		  break;
-		}
-	    }
-	}
-    }
-
-  if (new_prefix == NULL)
-    new_prefix = dwarf2_full_name (die, cu);
-
-  return new_prefix;
-}
-
 /* Given a pointer to a die which begins an enumeration, process all
    the dies that define the members of the enumeration, and create the
    symbol for the enumeration type.
@@ -5936,7 +5930,7 @@ read_typedef (struct die_info *die, stru
   const char *name = NULL;
   struct type *this_type;
 
-  name = dwarf2_full_name (die, cu);
+  name = dwarf2_full_name (NULL, die, cu);
   this_type = init_type (TYPE_CODE_TYPEDEF, 0,
 			 TYPE_FLAG_TARGET_STUB, NULL, objfile);
   TYPE_NAME (this_type) = (char *) name;
@@ -6764,7 +6758,8 @@ read_partial_die (struct partial_die_inf
 	    }
 	  break;
 	case DW_AT_MIPS_linkage_name:
-	  part_die->name = DW_STRING (&attr);
+	  if (cu->language == language_ada)
+	    part_die->name = DW_STRING (&attr);
 	  break;
 	case DW_AT_low_pc:
 	  has_low_pc_attr = 1;
@@ -8329,13 +8324,11 @@ new_symbol (struct die_info *die, struct
 
   baseaddr = ANOFFSET (objfile->section_offsets, SECT_OFF_TEXT (objfile));
 
-  if (die->tag != DW_TAG_namespace)
-    name = dwarf2_linkage_name (die, cu);
-  else
-    name = TYPE_NAME (type);
-
+  name = dwarf2_name (die, cu);
   if (name)
     {
+      const char *linkagename;
+
       sym = (struct symbol *) obstack_alloc (&objfile->objfile_obstack,
 					     sizeof (struct symbol));
       OBJSTAT (objfile, n_syms++);
@@ -8343,7 +8336,8 @@ new_symbol (struct die_info *die, struct
 
       /* Cache this symbol's name and the name's demangled form (if any).  */
       SYMBOL_LANGUAGE (sym) = cu->language;
-      SYMBOL_SET_NAMES (sym, name, strlen (name), 0, objfile);
+      linkagename = dwarf2_physname (name, die, cu);
+      SYMBOL_SET_NAMES (sym, linkagename, strlen (linkagename), 0, objfile);
 
       /* Default assumptions.
          Use the passed type or decode it from the die.  */
@@ -8568,7 +8562,8 @@ new_symbol (struct die_info *die, struct
 	  }
 	  break;
 	case DW_TAG_typedef:
-	  SYMBOL_LINKAGE_NAME (sym) = (char *) dwarf2_full_name (die, cu);
+	  SYMBOL_LINKAGE_NAME (sym)
+	    = (char *) dwarf2_full_name (name, die, cu);
 	  SYMBOL_CLASS (sym) = LOC_TYPEDEF;
 	  SYMBOL_DOMAIN (sym) = VAR_DOMAIN;
 	  add_symbol_to_list (sym, cu->list_in_scope);
@@ -8580,7 +8575,8 @@ new_symbol (struct die_info *die, struct
 	  add_symbol_to_list (sym, cu->list_in_scope);
 	  break;
 	case DW_TAG_enumerator:
-	  SYMBOL_LINKAGE_NAME (sym) = (char *) dwarf2_full_name (die, cu);
+	  SYMBOL_LINKAGE_NAME (sym)
+	    = (char *) dwarf2_full_name (name, die, cu);
 	  attr = dwarf2_attr (die, DW_AT_const_value, cu);
 	  if (attr)
 	    {
@@ -8617,8 +8613,7 @@ new_symbol (struct die_info *die, struct
       /* For the benefit of old versions of GCC, check for anonymous
 	 namespaces based on the demangled name.  */
       if (!processing_has_namespace_info
-	  && cu->language == language_cplus
-	  && dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu) != NULL)
+	  && cu->language == language_cplus)
 	cp_scan_for_anonymous_namespaces (sym);
     }
   return (sym);
@@ -9070,19 +9065,6 @@ sibling_die (struct die_info *die)
   return die->sibling;
 }
 
-/* Get linkage name of a die, return NULL if not found.  */
-
-static char *
-dwarf2_linkage_name (struct die_info *die, struct dwarf2_cu *cu)
-{
-  struct attribute *attr;
-
-  attr = dwarf2_attr (die, DW_AT_MIPS_linkage_name, cu);
-  if (attr && DW_STRING (attr))
-    return DW_STRING (attr);
-  return dwarf2_name (die, cu);
-}
-
 /* Get name of a die, return NULL if not found.  */
 
 static char *

^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-05 17:13                                             ` Keith Seitz
@ 2010-02-05 17:29                                               ` Daniel Jacobowitz
  2010-02-05 20:24                                                 ` Keith Seitz
  0 siblings, 1 reply; 50+ messages in thread
From: Daniel Jacobowitz @ 2010-02-05 17:29 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Fri, Feb 05, 2010 at 09:13:32AM -0800, Keith Seitz wrote:
> I hadn't either. Next iteration in attached patch.
> 
> BTW, while goofing around with the code a bit, it appears that since
> I wrote all of this many, many months ago, things have changed (for
> the better). physname_prefix and dependents are no longer necessary.
> We can use determine_prefix instead. I apologize that I did not catch
> this earlier.

This version looks much nicer.  I'm still confused about
die_needs_namespace, but I think we're almost done.

> +    case DW_TAG_variable:
> +      if (dwarf2_attr (die, DW_AT_specification, cu))
> +	{
> +	  struct dwarf2_cu *spec_cu = cu;
> +	  return die_needs_namespace (die_specification (die, &spec_cu),
> +				      spec_cu);
> +	}
> +
> +      return die_needs_namespace (die->parent, cu);

Recursing to follow the specification makes sense.  I don't think
recursing onto the parent makes sense though.  Won't this cause
the wrong answer for:

DW_TAG_subprogram
  DW_TAG_variable

?  If that doesn't matter, then I'm totally confused again :-)
That's your basic local variable.

Otherwise, everything looks OK.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-05 17:29                                               ` Daniel Jacobowitz
@ 2010-02-05 20:24                                                 ` Keith Seitz
  2010-02-05 20:57                                                   ` Daniel Jacobowitz
  0 siblings, 1 reply; 50+ messages in thread
From: Keith Seitz @ 2010-02-05 20:24 UTC (permalink / raw)
  To: gdb-patches

On 02/05/2010 09:24 AM, Daniel Jacobowitz wrote:
> Recursing to follow the specification makes sense.  I don't think
> recursing onto the parent makes sense though.  Won't this cause
> the wrong answer for:
>
> DW_TAG_subprogram
>    DW_TAG_variable
>
> ?  If that doesn't matter, then I'm totally confused again :-)
> That's your basic local variable.

It might be a gcc-ism, but we actually get a DW_TAG_lexical_block 
between DW_TAG_subprogram and DW_TAG_variable. I presume this is to mark 
the prologue. It is a very nice way to know that a variable is not 
global. O:-)

I can certainly understand why this is not such a desirable solution.

But at least I now remember (or rather -- I am now reminded) why I 
originally wrote what I did for this (with DW_AT_external and checking 
the parent DIE's tag).

After revisiting that, I think it clearer to understand if I invert the 
original test:

     case DW_TAG_variable:
       {
	struct attribute *attr;

	/* We only need to prefix "globally" visible variables.  These include
	   any variable marked with DW_AT_external or any variable that
	   lives in a namespace.  [Variables in anonymous namespaces
	   require prefixing, but they are not DW_AT_external.]  */

	if (dwarf2_attr (die, DW_AT_specification, cu))
	  {
	    struct dwarf2_cu *spec_cu = cu;
	    return die_needs_namespace (die_specification (die, &spec_cu),
					spec_cu);
	  }

	attr = dwarf2_attr (die, DW_AT_external, cu);
	if (attr || die->parent->tag == DW_TAG_namespace)
	  return 1;

	return 0;
       }

How does that look?

Keith


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-05 20:24                                                 ` Keith Seitz
@ 2010-02-05 20:57                                                   ` Daniel Jacobowitz
  2010-02-05 23:10                                                     ` Keith Seitz
  0 siblings, 1 reply; 50+ messages in thread
From: Daniel Jacobowitz @ 2010-02-05 20:57 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Fri, Feb 05, 2010 at 12:23:48PM -0800, Keith Seitz wrote:
> It might be a gcc-ism, but we actually get a DW_TAG_lexical_block
> between DW_TAG_subprogram and DW_TAG_variable. I presume this is to
> mark the prologue. It is a very nice way to know that a variable is
> not global. O:-)

It's a GCC-ism :-)

> After revisiting that, I think it clearer to understand if I invert
> the original test:
> 
>     case DW_TAG_variable:
>       {
> 	struct attribute *attr;
> 
> 	/* We only need to prefix "globally" visible variables.  These include
> 	   any variable marked with DW_AT_external or any variable that
> 	   lives in a namespace.  [Variables in anonymous namespaces
> 	   require prefixing, but they are not DW_AT_external.]  */
> 
> 	if (dwarf2_attr (die, DW_AT_specification, cu))
> 	  {
> 	    struct dwarf2_cu *spec_cu = cu;
> 	    return die_needs_namespace (die_specification (die, &spec_cu),
> 					spec_cu);
> 	  }

On this part we are in complete agreement.

> 	attr = dwarf2_attr (die, DW_AT_external, cu);
> 	if (attr || die->parent->tag == DW_TAG_namespace)
> 	  return 1;
> 
> 	return 0;
>       }
> 
> How does that look?

I'm not sure, but I think it's close enough for now.

(Things I'm wondering about that we can sort out later: namespace X {
int f() { extern int y; } }, does y go in a namespace?  What
namespace?  It certainly doesn't go in X::f()::y but I don't know what
GCC emits.  namespace X { class Y { static int x; } }, is that
DW_AT_extern?)

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-05 20:57                                                   ` Daniel Jacobowitz
@ 2010-02-05 23:10                                                     ` Keith Seitz
  2010-02-05 23:46                                                       ` Daniel Jacobowitz
  0 siblings, 1 reply; 50+ messages in thread
From: Keith Seitz @ 2010-02-05 23:10 UTC (permalink / raw)
  To: gdb-patches

On 02/05/2010 12:57 PM, Daniel Jacobowitz wrote:
> (Things I'm wondering about that we can sort out later: namespace X {
> int f() { extern int y; } }, does y go in a namespace?  What
> namespace?  It certainly doesn't go in X::f()::y but I don't know what
> GCC emits.

I would expect some DIE to contain a DW_AT_specification that refers to 
the real y, and that we use that to determine what to do.

The only testcase I could come up with your example was with "y" defined 
inside X, and the debuginfo behave as above. I cannot seem to get gcc to 
resolve "y" to anything but X::y, but then I'm no expert on namespaces & 
extern. Not even a novice.

> namespace X { class Y { static int x; } }, is that DW_AT_extern?)

Yes, it is DW_AT_external.

Keith


^ permalink raw reply	[flat|nested] 50+ messages in thread

* Re: [RFA 2/4] dwarf2_physname
  2010-02-05 23:10                                                     ` Keith Seitz
@ 2010-02-05 23:46                                                       ` Daniel Jacobowitz
  0 siblings, 0 replies; 50+ messages in thread
From: Daniel Jacobowitz @ 2010-02-05 23:46 UTC (permalink / raw)
  To: Keith Seitz; +Cc: gdb-patches

On Fri, Feb 05, 2010 at 03:10:46PM -0800, Keith Seitz wrote:
> Yes, it is DW_AT_external.

OK.  Let's run with the version you've got, then.

-- 
Daniel Jacobowitz
CodeSourcery


^ permalink raw reply	[flat|nested] 50+ messages in thread

end of thread, other threads:[~2010-02-05 23:46 UTC | newest]

Thread overview: 50+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-11-20 21:20 [RFA 2/4] dwarf2_physname Keith Seitz
2009-11-20 22:10 ` Daniel Jacobowitz
2009-11-21  0:04   ` Tom Tromey
2009-11-21  3:46     ` Frank Ch. Eigler
2009-11-23 18:06       ` Tom Tromey
2009-11-23 19:00         ` Daniel Jacobowitz
2009-11-23 16:52   ` Keith Seitz
2009-11-23 17:08     ` Daniel Jacobowitz
2009-11-24 19:20       ` Sami Wagiaalla
2010-01-27 17:10         ` Sami Wagiaalla
2009-12-08 19:47   ` Keith Seitz
2009-12-14 19:33     ` Keith Seitz
2009-12-17 20:19       ` Tom Tromey
2009-12-17 20:28         ` Daniel Jacobowitz
2009-12-17 22:39           ` Paul Pluzhnikov
2009-12-22 18:35           ` Tom Tromey
2009-12-22 19:24             ` Daniel Jacobowitz
2010-01-20 20:37               ` Keith Seitz
2010-01-26 21:17                 ` Daniel Jacobowitz
2010-01-27 19:12                   ` Keith Seitz
2010-01-28 20:22                     ` Keith Seitz
2010-01-28 20:24                       ` Daniel Jacobowitz
2010-01-28 23:41                         ` Keith Seitz
2010-02-01 16:48                           ` Daniel Jacobowitz
2010-02-01 19:32                             ` Keith Seitz
2010-02-01 19:39                               ` Daniel Jacobowitz
2010-02-01 21:52                                 ` Keith Seitz
2010-02-01 22:19                                   ` Daniel Jacobowitz
2010-02-02 23:23                                     ` Keith Seitz
2010-02-02 23:31                                       ` Keith Seitz
2010-02-03  2:46                                       ` Daniel Jacobowitz
2010-02-04 17:48                                         ` Tom Tromey
2010-02-04 18:14                                           ` Daniel Jacobowitz
2010-02-05 17:13                                             ` Keith Seitz
2010-02-05 17:29                                               ` Daniel Jacobowitz
2010-02-05 20:24                                                 ` Keith Seitz
2010-02-05 20:57                                                   ` Daniel Jacobowitz
2010-02-05 23:10                                                     ` Keith Seitz
2010-02-05 23:46                                                       ` Daniel Jacobowitz
2010-02-04 17:21                             ` Tom Tromey
2010-02-04 17:25                               ` Daniel Jacobowitz
2009-11-23  7:31 ` André Pönitz
2009-11-23 16:57   ` Keith Seitz
2009-11-23 17:20     ` Tom Tromey
2009-11-24  7:22     ` André Pönitz
2009-11-24 22:54       ` Tom Tromey
2009-11-25  9:16         ` André Pönitz
2009-11-25 18:14           ` Tom Tromey
2009-11-23 17:15   ` Tom Tromey
2009-11-24 22:11 ` Joel Brobecker

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox