From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 5795 invoked by alias); 18 Aug 2006 04:11:25 -0000 Received: (qmail 5748 invoked by uid 22791); 18 Aug 2006 04:11:21 -0000 X-Spam-Check-By: sourceware.org Received: from nevyn.them.org (HELO nevyn.them.org) (66.93.172.17) by sourceware.org (qpsmtpd/0.31.1) with ESMTP; Fri, 18 Aug 2006 04:11:16 +0000 Received: from drow by nevyn.them.org with local (Exim 4.54) id 1GDvhR-0003SQ-01 for gdb-patches@sourceware.org; Fri, 18 Aug 2006 00:11:13 -0400 Date: Fri, 18 Aug 2006 09:21:00 -0000 From: Daniel Jacobowitz To: gdb-patches@sourceware.org Subject: Re: [rfc] Recognize GCC pointer to member function DWARF2 descriptions Message-ID: <20060818041112.GB13020@nevyn.them.org> Mail-Followup-To: gdb-patches@sourceware.org References: <20060807025740.GA3018@nevyn.them.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20060807025740.GA3018@nevyn.them.org> User-Agent: Mutt/1.5.11+cvs20060403 X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-08/txt/msg00120.txt.bz2 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 * 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))