Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Keith Seitz <kseitz@uglyboxes.com>
To: gdb-patches@sourceware.org
Subject: [RFA 2/4] dwarf2_physname
Date: Fri, 20 Nov 2009 21:20:00 -0000	[thread overview]
Message-ID: <4B0707E7.5010308@uglyboxes.com> (raw)

[-- 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;

             reply	other threads:[~2009-11-20 21:20 UTC|newest]

Thread overview: 50+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-11-20 21:20 Keith Seitz [this message]
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

Reply instructions:

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

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

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

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

  git send-email \
    --in-reply-to=4B0707E7.5010308@uglyboxes.com \
    --to=kseitz@uglyboxes.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

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

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