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
next 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