From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10979 invoked by alias); 6 Jan 2004 17:05:33 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 10970 invoked from network); 6 Jan 2004 17:05:29 -0000 Received: from unknown (HELO nevyn.them.org) (66.93.172.17) by sources.redhat.com with SMTP; 6 Jan 2004 17:05:29 -0000 Received: from drow by nevyn.them.org with local (Exim 4.30 #1 (Debian)) id 1Adudv-0001G2-7I; Tue, 06 Jan 2004 12:05:23 -0500 Date: Tue, 06 Jan 2004 17:05:00 -0000 From: Daniel Jacobowitz To: Michael Elizabeth Chastain Cc: gdb-patches@sources.redhat.com Subject: Re: [rfc/cp] method stub assertions Message-ID: <20040106170522.GA29597@nevyn.them.org> Mail-Followup-To: Michael Elizabeth Chastain , gdb-patches@sources.redhat.com References: <20040106042841.584854B35A@berman.michael-chastain.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20040106042841.584854B35A@berman.michael-chastain.com> User-Agent: Mutt/1.5.1i X-SW-Source: 2004-01/txt/msg00138.txt.bz2 On Mon, Jan 05, 2004 at 11:28:41PM -0500, Michael Chastain wrote: > (gdb) ptype pfii > type = int (*)(int) > > (gdb) ptype pfiAi > type = int (*)(A &, int) > > (gdb) ptype pfAii > type = struct { > int (*__pfn)(A *, int); > int __delta; > } > > (gdb) ptype A::bad6 > type = int (A * const, int) > > (gdb) ptype &A::bad6 > type = int (*)(A * const, int) > > The first four of those are okay with me. pfAii is not only a > different type from a pointer to an ordinary function, > but the type has a different size! That's really unfortunate debug info. Of course, GDB isn't prepared to handle DW_TAG_ptr_to_member_type. But now that we have a working location expression parser it would not be difficult. Then GCC could emit the right information. > The last one, &A::bad6, bothers me a lot. The address-of operator > applied to a (non-static) member function should *not* return a > plain pointer-to-function. Output #5 should *not* look like #2. > It should look like: > > (gdb) ptype &A::bad6 > type = int (A::*)(int) > > I'm willing to slide on the "A * const" hidden parameter, > but not on the "A::*" instead of "*". > > I think that gdb does not distinguish between pointer-to-function and > PMF. PMF's always carry a class argument with them, but plain PF's > never need them. I suspect gdb is mixing the TYPE_CODE's instead of using > separate TYPE_CODE's. > > The existing scheme is something like: > > TYPE_CODE_MEMBER > TYPE_CODE_METHOD > domain type > > But I want it to be more: > > TYPE_CODE_MEMBER > domain type > TYPE_CODE_METHOD That's a nice hypothesis. Unfortunately it's completely wrong :) First of all, TYPE_CODE_MEMBER and TYPE_CODE_METHOD are siblings. MEMBER is used for data variables, not to wrap methods. Secondly, take a look at the type of A::bad6 - put a breakpoint in c_type_print_varspec_prefix. It's a TYPE_CODE_FUNCTION. Why is that? It's because A::bad6 is a function. Now, if you take a look at its first argument, and walk the chain down: (top-gdb) p *type.main_type $19 = {code = TYPE_CODE_FUNC, upper_bound_type = BOUND_SIMPLE, lower_bound_type = BOUND_SIMPLE, name = 0x0, tag_name = 0x0, objfile = 0x82cfea0, target_type = 0x82d8320, flags = 128, nfields = 2, vptr_fieldno = -1, fields = 0x82d85a8, vptr_basetype = 0x0, type_specific = {cplus_stuff = 0x0, floatformat = 0x0}} (top-gdb) p type.main_type.fields.type.main_type.target_type.main_type.type_specific.cplus_stuff.fn_fieldlists[3].fn_fields[0].type.main_type[0] $18 = {code = TYPE_CODE_METHOD, upper_bound_type = BOUND_SIMPLE, lower_bound_type = BOUND_SIMPLE, name = 0x0, tag_name = 0x0, objfile = 0x82cfea0, target_type = 0x82d8320, flags = 0, nfields = 2, vptr_fieldno = 0, fields = 0x82d8440, vptr_basetype = 0x82d7fd4, type_specific = {cplus_stuff = 0x0, floatformat = 0x0}} The debug information for A::bad6 does not specify that it is a method. Rather only the debug info for class A specifies that it has a method named A::bad6. Take a look at a readelf -wi dump of your testcase to see how this works. It may be that A::bad6 should have TYPE_CODE_METHOD. Fixing this would require some surgery to the stabs and dwarf readers. I suspect that hpread does it already. Or it may be that TYPE_CODE_METHOD should be eliminated and they both should be TYPE_CODE_FUNCTION. That's hard to say. > Every time you create a TYPE_CODE_MEMBER, you should know what the > domain type is, and store it up one node, not down in the > TYPE_CODE_METHOD node. And every time you use a TYPE_CODE_MEMBER, you > have to use the domain type. And if you're not dealing with > pointer-to-member, you don't need the domain type. It's an attribute > of the pointer-to-member, not an attribute of the member! > > Bleagh. I'm probably butchering the actual gdb data structures here. > Need to read more. The current structure of this says that if we get a TYPE_CODE_POINTER and its target type is TYPE_CODE_METHOD or TYPE_CODE_MEMBER, then it's a pointer-to-member. You're suggesting that we have a TYPE_CODE_PTRMEM instead. This matches what a lot of other similar programs do, so maybe it makes sense. But unless we can make A::bad6 have TYPE_CODE_METHOD we still won't know to create a TYPE_CODE_PTRMEM when its address is taken, so I think this can come later. > > Do static methods have TYPE_CODE_METHOD, and should they? > > That's the question. > > I think they currently do. And then they have TYPE_FLAG_STATIC to > distinguish them from other types. > > Static methods have to appear with other methods because they > participate in overload resolution. Currently they do appear as TYPE_CODE_METHOD. I think that they probably shouldn't. A pointer to a static method is a function pointer, not a pointer-to-member. Similarly static variables should probably not be TYPE_CODE_MEMBER. -- Daniel Jacobowitz MontaVista Software Debian GNU/Linux Developer