Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Keith Seitz <keiths@redhat.com>
To: gdb-patches@sourceware.org
Subject: [RFA] dwarf2_physname
Date: Mon, 31 Aug 2009 22:51:00 -0000	[thread overview]
Message-ID: <4A9C358E.2050904@redhat.com> (raw)

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

Hi,

I have been working on archer's expression parsing (and therefore symbol 
table madness) for the past year or so. I've managed to fix a lot of C++ 
problems on my archer-keiths-expr-cumulative branch. I would like to 
start attempting to push many of these patches into mainline FSF GDB, 
but of course, as with any large task of this type, the patches are HUGE 
(5500+ lines).

In an effort to help maintainers assess the code in smaller chunks 
without introducing new, temporary test suite failures, I'm going to try 
something "different" -- this patch, and the follow-ons, will not 
actually do anything until a final patch turns it all on. My hope is 
that this will be minimally intrusive to GDB's code base, especially 
given all the talk of a new release.

To start, I would like to submit a patch which is the beginnings of 
removing GDB's use of the DWARF2 quasi-attribute 
DW_AT_MIPS_linkage_name. Instead of using this attribute, GDB will start 
generating physical names itself.

Again, this patch will not actually change the current code path; the 
main entry, dwarf2_physname is not called (but you can imagine, it will 
replace all dwarf2_linkage_name calls). Therefore, there are no test 
suite regressions of any kind.

Keith

ChangeLog
2009-08-31  Keith Seitz  <keiths@redhat.com>

	* dwarf2read.c (die_list): New file global.
	(physname_prefix): New function.
	(physname_prefix_1): New function.
	(dwarf2_physname): New function.
	(die_needs_namespace): New function.

	Based on work from Daniel Jacobowitz  <dan@codesourcery.com>:
	* typeprint.h (c_type_print_args): Declare.
	* ui-file.h (ui_file_obsavestring): Declare.
	* c-typeprint.c (c_type_print_args): Add to global namespace.
	Add "show_articifical" parameter and only print them when
	requested.
	* ui-file.c (do_ui_file_obsavestring): New function.
	(ui_file_obsavestring): New function.

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

Index: dwarf2read.c
===================================================================
RCS file: /cvs/src/src/gdb/dwarf2read.c,v
retrieving revision 1.325
diff -u -p -r1.325 dwarf2read.c
--- dwarf2read.c	28 Aug 2009 10:49:05 -0000	1.325
+++ dwarf2read.c	31 Aug 2009 20:37:23 -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"
@@ -691,6 +694,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
@@ -804,6 +812,8 @@ static void add_partial_symbol (struct p
 
 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,
 				   int need_pc, struct dwarf2_cu *cu);
@@ -949,6 +959,11 @@ static struct type *read_type_die (struc
 
 static char *determine_prefix (struct die_info *die, 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 *typename_concat (struct obstack *,
                               const char *prefix, 
                               const char *suffix,
@@ -1036,6 +1051,8 @@ static void process_die (struct die_info
 
 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 *);
 
@@ -2577,6 +2594,44 @@ pdi_needs_namespace (enum dwarf_tag tag)
     }
 }
 
+/* Determine 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:
+      {
+	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;
+    }
+}
+
 /* 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.  */
@@ -8914,6 +8969,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,
@@ -8976,6 +9121,80 @@ dwarf2_linkage_name (struct die_info *di
   return dwarf2_name (die, cu);
 }
 
+/* Construct a physname for the given DIE in CU. */
+
+static char *
+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);
+
+	  c_type_print_args (type, buf, 0);
+
+	  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.  */
 
 static char *
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	31 Aug 2009 20:37:23 -0000
@@ -26,4 +26,6 @@ void print_type_scalar (struct type * ty
 
 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);
 #endif
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	31 Aug 2009 20:37:23 -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: c-typeprint.c
===================================================================
RCS file: /cvs/src/src/gdb/c-typeprint.c,v
retrieving revision 1.47
diff -u -p -r1.47 c-typeprint.c
--- c-typeprint.c	2 Jul 2009 12:57:14 -0000	1.47
+++ c-typeprint.c	31 Aug 2009 20:37:23 -0000
@@ -40,8 +40,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,
@@ -355,10 +353,12 @@ 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.  */
 
-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)
 {
   int i, len;
   struct field *args;
@@ -370,6 +370,9 @@ 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, ", ");
@@ -593,7 +596,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);
       c_type_print_varspec_suffix (TYPE_TARGET_TYPE (type), stream, show,
 				   passed_a_ptr, 0);
       break;
Index: ui-file.c
===================================================================
RCS file: /cvs/src/src/gdb/ui-file.c,v
retrieving revision 1.18
diff -u -p -r1.18 ui-file.c
--- ui-file.c	14 Aug 2009 00:32:32 -0000	1.18
+++ ui-file.c	31 Aug 2009 20:37:23 -0000
@@ -22,6 +22,7 @@
 
 #include "defs.h"
 #include "ui-file.h"
+#include "gdb_obstack.h"
 #include "gdb_string.h"
 
 #include <errno.h>
@@ -297,6 +298,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

             reply	other threads:[~2009-08-31 20:42 UTC|newest]

Thread overview: 22+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-08-31 22:51 Keith Seitz [this message]
2009-08-31 23:10 ` Michael Eager
2009-08-31 23:23   ` Keith Seitz
2009-08-31 23:35     ` Michael Eager
2009-09-01 22:11     ` Daniel Jacobowitz
2009-09-01 22:27       ` Daniel Jacobowitz
2009-09-01 23:18       ` Michael Eager
2009-09-01 23:37         ` Daniel Jacobowitz
2009-09-02  1:12           ` Michael Eager
2009-09-01 23:26       ` Keith Seitz
2009-09-01 23:42         ` Daniel Jacobowitz
2009-09-14 18:39           ` Keith Seitz
2009-09-14 22:48             ` Daniel Jacobowitz
2009-09-14 23:56               ` Keith Seitz
2009-09-15 13:32                 ` Daniel Jacobowitz
2009-09-15 15:53                   ` Keith Seitz
2009-09-15 16:12                     ` Daniel Jacobowitz
2009-09-16 20:27                       ` Keith Seitz
2009-09-18 22:34                         ` Tom Tromey
     [not found]   ` <m37hwjy2tl.fsf@fleche.redhat.com>
2009-09-01  0:06     ` Michael Eager
2009-09-01 21:27 ` Tom Tromey
2009-09-01 22:10   ` Keith Seitz

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=4A9C358E.2050904@redhat.com \
    --to=keiths@redhat.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