Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
From: Daniel Jacobowitz <drow@false.org>
To: gdb-patches@sourceware.org
Subject: Re: [rfc] Recognize GCC pointer to member function DWARF2 descriptions
Date: Fri, 18 Aug 2006 09:21:00 -0000	[thread overview]
Message-ID: <20060818041112.GB13020@nevyn.them.org> (raw)
In-Reply-To: <20060807025740.GA3018@nevyn.them.org>

On Sun, Aug 06, 2006 at 10:57:40PM -0400, Daniel Jacobowitz wrote:
> GCC emits DW_TAG_ptr_to_member_type for pointers to member data, but not
> for pointers to member functions.  I plan to fix this in GCC eventually,
> but in the mean time, this does some pattern recognition on the GCC
> output to convert it into a pointer to member.  It recognizes structures
> of the form:
> 
> struct {
>   void (*__pfn) (args, ...);
>   ptrdiff_t __delta;
> };

I checked this in as attached, with a typo fix.  The underlying issue
being worked around here is GCC PR debug/28767.

-- 
Daniel Jacobowitz
CodeSourcery

2006-08-18  Daniel Jacobowitz  <dan@codesourcery.com>

	* dwarf2read.c (quirk_gcc_member_function_pointer): New.
	(read_structure_type): Call it.

Index: src/gdb/dwarf2read.c
===================================================================
--- src.orig/gdb/dwarf2read.c	2006-08-05 10:10:11.000000000 -0400
+++ src/gdb/dwarf2read.c	2006-08-06 22:52:02.000000000 -0400
@@ -3708,6 +3708,69 @@ is_vtable_name (const char *name, struct
   return 0;
 }
 
+/* GCC outputs unnamed structures that are really pointers to member
+   functions, with the ABI-specified layout.  If DIE (from CU) describes
+   such a structure, set its type, and return nonzero.  Otherwise return
+   zero.  */
+
+static int
+quirk_gcc_member_function_pointer (struct die_info *die, struct dwarf2_cu *cu)
+{
+  struct objfile *objfile = cu->objfile;
+  struct type *type;
+  struct die_info *pfn_die, *delta_die;
+  struct attribute *pfn_name, *delta_name;
+  struct type *pfn_type, *domain_type;
+
+  /* Check for a structure with no name and two children.  */
+  if (die->tag != DW_TAG_structure_type
+      || dwarf2_attr (die, DW_AT_name, cu) != NULL
+      || die->child == NULL
+      || die->child->sibling == NULL
+      || (die->child->sibling->sibling != NULL
+	  && die->child->sibling->sibling->tag != DW_TAG_padding))
+    return 0;
+
+  /* Check for __pfn and __delta members.  */
+  pfn_die = die->child;
+  pfn_name = dwarf2_attr (pfn_die, DW_AT_name, cu);
+  if (pfn_die->tag != DW_TAG_member
+      || pfn_name == NULL
+      || DW_STRING (pfn_name) == NULL
+      || strcmp ("__pfn", DW_STRING (pfn_name)) != 0)
+    return 0;
+
+  delta_die = pfn_die->sibling;
+  delta_name = dwarf2_attr (delta_die, DW_AT_name, cu);
+  if (delta_die->tag != DW_TAG_member
+      || delta_name == NULL
+      || DW_STRING (delta_name) == NULL
+      || strcmp ("__delta", DW_STRING (delta_name)) != 0)
+    return 0;
+
+  /* Find the type of the method.  */
+  pfn_type = die_type (pfn_die, cu);
+  if (pfn_type == NULL
+      || TYPE_CODE (pfn_type) != TYPE_CODE_PTR
+      || TYPE_CODE (TYPE_TARGET_TYPE (pfn_type)) != TYPE_CODE_FUNC)
+    return 0;
+
+  /* Look for the "this" argument.  */
+  pfn_type = TYPE_TARGET_TYPE (pfn_type);
+  if (TYPE_NFIELDS (pfn_type) == 0
+      || TYPE_CODE (TYPE_FIELD_TYPE (pfn_type, 0)) != TYPE_CODE_PTR)
+    return 0;
+
+  domain_type = TYPE_TARGET_TYPE (TYPE_FIELD_TYPE (pfn_type, 0));
+  type = alloc_type (objfile);
+  smash_to_method_type (type, domain_type, TYPE_TARGET_TYPE (pfn_type),
+			TYPE_FIELDS (pfn_type), TYPE_NFIELDS (pfn_type),
+			TYPE_VARARGS (pfn_type));
+  type = lookup_pointer_type (type);
+  set_die_type (die, type, cu);
+
+  return 1;
+}
 
 /* Called when we find the DIE that starts a structure or union scope
    (definition) to process all dies that define the members of the
@@ -3737,8 +3800,10 @@ read_structure_type (struct die_info *di
   if (die->type)
     return;
 
-  type = alloc_type (objfile);
+  if (quirk_gcc_member_function_pointer (die, cu))
+    return;
 
+  type = alloc_type (objfile);
   INIT_CPLUS_SPECIFIC (type);
   attr = dwarf2_attr (die, DW_AT_name, cu);
   if (attr && DW_STRING (attr))


  reply	other threads:[~2006-08-18  4:11 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2006-08-07  2:57 Daniel Jacobowitz
2006-08-18  9:21 ` Daniel Jacobowitz [this message]
2006-08-18 13:26   ` Mark Kettenis
2006-08-19  3:22     ` Daniel Jacobowitz

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=20060818041112.GB13020@nevyn.them.org \
    --to=drow@false.org \
    --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