This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

FYI: fix 'this' lookup for lambdas


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  <tromey@redhat.com>

	* 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) <OP_THIS>: 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;
 }
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]