From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20277 invoked by alias); 17 Jun 2011 20:46:44 -0000 Received: (qmail 20267 invoked by uid 22791); 17 Jun 2011 20:46:42 -0000 X-SWARE-Spam-Status: No, hits=-6.1 required=5.0 tests=AWL,BAYES_00,KAM_STOCKGEN,RCVD_IN_DNSWL_HI,SPF_HELO_PASS,T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 17 Jun 2011 20:46:23 +0000 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id p5HKkN5j028077 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Fri, 17 Jun 2011 16:46:23 -0400 Received: from ns3.rdu.redhat.com (ns3.rdu.redhat.com [10.11.255.199]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with ESMTP id p5HKkNFj020522; Fri, 17 Jun 2011 16:46:23 -0400 Received: from opsy.redhat.com (ovpn01.gateway.prod.ext.phx2.redhat.com [10.5.9.1]) by ns3.rdu.redhat.com (8.13.8/8.13.8) with ESMTP id p5HKkMnH032471; Fri, 17 Jun 2011 16:46:22 -0400 Received: by opsy.redhat.com (Postfix, from userid 500) id 9F0B5378256; Fri, 17 Jun 2011 14:46:21 -0600 (MDT) From: Tom Tromey To: gdb-patches@sourceware.org Subject: FYI: fix 'this' lookup for lambdas Date: Fri, 17 Jun 2011 20:46:00 -0000 Message-ID: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2011-06/txt/msg00238.txt.bz2 I'm checking this in on the trunk. Jason recently changed g++ to emit better debuginfo for the C++0x lambda construct: http://gcc.gnu.org/ml/gcc-patches/2011-06/msg01358.html This patch is designed to make GDB mostly do the right thing automatically; it achieves this by introducing locals into the lambda which have the same name as the captured variables. However, in a lambda, "this" is special and refers to the captured "this", not the object pointer for the lambda's (artificial) class. G++ emits a variable named "this" in the lambda's body that refers to the captured "this". This patch changes GDB to do the right thing in this case. The change is simple: instead of always searching for "this" in the outermost block of the function, look in all the blocks. This way, GDB automatically picks up the captured "this". I think this change is safe because ordinary code has no way to introduce a shadowing variable named "this". So, in the absence of lambdas, GDB will simply pick up the same definition it did before. Built and regtested by the buildbot. Tom 2011-06-17 Tom Tromey * valops.c (value_of_this): Use lookup_language_this. * symtab.h (lookup_language_this): Declare. * symtab.c (lookup_language_this): New function. (lookup_symbol_aux): Use lookup_language_this. * ax-gdb.c (gen_expr) : Use lookup_language_this. Index: ax-gdb.c =================================================================== RCS file: /cvs/src/src/gdb/ax-gdb.c,v retrieving revision 1.87 diff -u -r1.87 ax-gdb.c --- ax-gdb.c 18 May 2011 20:19:51 -0000 1.87 +++ ax-gdb.c 17 Jun 2011 20:40:25 -0000 @@ -2138,18 +2138,17 @@ case OP_THIS: { char *this_name; - struct symbol *func, *sym; + struct symbol *sym, *func; struct block *b; + const struct language_defn *lang; - func = block_linkage_function (block_for_pc (ax->scope)); - this_name = language_def (SYMBOL_LANGUAGE (func))->la_name_of_this; - b = SYMBOL_BLOCK_VALUE (func); - - /* Calling lookup_block_symbol is necessary to get the LOC_REGISTER - symbol instead of the LOC_ARG one (if both exist). */ - sym = lookup_block_symbol (b, this_name, VAR_DOMAIN); + b = block_for_pc (ax->scope); + func = block_linkage_function (b); + lang = language_def (SYMBOL_LANGUAGE (func)); + + sym = lookup_language_this (lang, b); if (!sym) - error (_("no `%s' found"), this_name); + error (_("no `%s' found"), lang->la_name_of_this); gen_var_ref (exp->gdbarch, ax, value, sym); Index: symtab.c =================================================================== RCS file: /cvs/src/src/gdb/symtab.c,v retrieving revision 1.275 diff -u -r1.275 symtab.c --- symtab.c 10 Jun 2011 21:50:54 -0000 1.275 +++ symtab.c 17 Jun 2011 20:40:25 -0000 @@ -1090,6 +1090,29 @@ is_a_field_of_this); } +/* Look up the `this' symbol for LANG in BLOCK. Return the symbol if + found, or NULL if not found. */ + +struct symbol * +lookup_language_this (const struct language_defn *lang, + const struct block *block) +{ + if (lang->la_name_of_this == NULL || block == NULL) + return NULL; + + while (1) + { + struct symbol *sym; + + sym = lookup_block_symbol (block, lang->la_name_of_this, VAR_DOMAIN); + if (sym != NULL) + return sym; + if (BLOCK_FUNCTION (block)) + return NULL; + block = BLOCK_SUPERBLOCK (block); + } +} + /* Behave like lookup_symbol except that NAME is the natural name of the symbol that we're looking for and, if LINKAGE_NAME is non-NULL, ensure that the symbol's linkage name matches as @@ -1123,20 +1146,10 @@ langdef = language_def (language); - if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL - && block != NULL) + if (is_a_field_of_this != NULL) { - struct symbol *sym = NULL; - const struct block *function_block = block; + struct symbol *sym = lookup_language_this (langdef, block); - /* 'this' is only defined in the function's block, so find the - enclosing function block. */ - for (; function_block && !BLOCK_FUNCTION (function_block); - function_block = BLOCK_SUPERBLOCK (function_block)); - - if (function_block && !dict_empty (BLOCK_DICT (function_block))) - sym = lookup_block_symbol (function_block, langdef->la_name_of_this, - VAR_DOMAIN); if (sym) { struct type *t = sym->type; Index: symtab.h =================================================================== RCS file: /cvs/src/src/gdb/symtab.h,v retrieving revision 1.183 diff -u -r1.183 symtab.h --- symtab.h 14 Jun 2011 16:49:41 -0000 1.183 +++ symtab.h 17 Jun 2011 20:40:25 -0000 @@ -33,6 +33,7 @@ struct axs_value; struct agent_expr; struct program_space; +struct language_defn; /* Some of the structures in this file are space critical. The space-critical structures are: @@ -917,6 +918,9 @@ const struct block *block, const domain_enum domain); +extern struct symbol *lookup_language_this (const struct language_defn *lang, + const struct block *block); + /* Lookup a symbol only in the file static scope of all the objfiles. */ struct symbol *lookup_static_symbol_aux (const char *name, Index: valops.c =================================================================== RCS file: /cvs/src/src/gdb/valops.c,v retrieving revision 1.278 diff -u -r1.278 valops.c --- valops.c 17 Jun 2011 20:35:09 -0000 1.278 +++ valops.c 17 Jun 2011 20:40:26 -0000 @@ -3603,13 +3603,12 @@ struct value * value_of_this (const struct language_defn *lang, int complain) { - struct symbol *func, *sym; + struct symbol *sym; struct block *b; struct value * ret; struct frame_info *frame; - const char *name = lang->la_name_of_this; - if (!name) + if (!lang->la_name_of_this) { if (complain) error (_("no `this' in current language")); @@ -3625,39 +3624,21 @@ return 0; } - func = get_frame_function (frame); - if (!func) - { - if (complain) - error (_("no `%s' in nameless context"), name); - else - return 0; - } - - b = SYMBOL_BLOCK_VALUE (func); - if (dict_empty (BLOCK_DICT (b))) - { - if (complain) - error (_("no args, no `%s'"), name); - else - return 0; - } + b = get_frame_block (frame, NULL); - /* Calling lookup_block_symbol is necessary to get the LOC_REGISTER - symbol instead of the LOC_ARG one (if both exist). */ - sym = lookup_block_symbol (b, name, VAR_DOMAIN); + sym = lookup_language_this (lang, b); if (sym == NULL) { if (complain) error (_("current stack frame does not contain a variable named `%s'"), - name); + lang->la_name_of_this); else return NULL; } ret = read_var_value (sym, frame); if (ret == 0 && complain) - error (_("`%s' argument unreadable"), name); + error (_("`%s' argument unreadable"), lang->la_name_of_this); return ret; }