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]

Re: [patch 3/8] Types GC [display_uses_solib_p to exp_iterate]


On Tue, 09 Jun 2009 22:09:29 +0200, Tom Tromey wrote:
> Instead, I think this needs a new language method of some kind, with an
> Ada-specific implementation that handles this case.

Attached.  Tested on FSF GDB HEAD on {x86_64,i686}-fedora-linux-gnu.

`objfile2' below will get dropped with further patches which hook
clear_dangling_display_expressions to be called per objfile (instead of per
solib).  But it makes the patch independent this way.

former notes:

exp_iterate in this patch already supports the `struct type' callback which is
not used here.  It gets used in the patch 6/8 (just made the split easier).

solib_contains_address_p gets replaced by block_objfile which has a different
principle of its operation; still both functions should return the same
results.


Thanks,
Jan


gdb/
2009-07-02  Jan Kratochvil  <jan.kratochvil@redhat.com>

	Generalize display_uses_solib_p as exp_uses_objfile.
	* ada-lang.c (ada_operator_check): New function.
	(ada_exp_descriptor): Fill-in the field operator_check.
	* block.c (block_objfile): New function.
	* block.h (block_objfile): New prototype.
	* c-lang.c (exp_descriptor_c): Fill-in the field operator_check.
	* jv-lang.c (exp_descriptor_java): Likewise.
	* m2-lang.c (exp_descriptor_modula2): Likewise.
	* scm-lang.c (exp_descriptor_scm): Likewise.
	* parse.c (exp_descriptor_standard): Likewise.
	(operator_check_standard): New function.
	(exp_iterate, exp_uses_objfile_iter, exp_uses_objfile): New functions.
	* parser-defs.h (struct exp_descriptor): New field operator_check.
	(operator_check_standard, exp_uses_objfile): New declarations.
	* printcmd.c: Remove the inclusion of solib.h.
	(display_uses_solib_p): Remove the function.
	(clear_dangling_display_expressions): New variable `objfile2'. Call
	block_objfile and exp_uses_objfile instead of display_uses_solib_p.

diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 520b401..a00c505 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -10834,6 +10834,40 @@ ada_operator_length (struct expression *exp, int pc, int *oplenp, int *argsp)
     }
 }
 
+/* Implementation of the exp_descriptor method operator_check.  */
+
+static int
+ada_operator_check (struct expression *exp, int pos,
+		    int (*type_func) (struct type *type, void *data),
+		    int (*objfile_func) (struct objfile *objfile, void *data),
+		    void *data)
+{
+  const union exp_element *const elts = exp->elts;
+  struct type *type = NULL;
+
+  switch (elts[pos].opcode)
+    {
+      case UNOP_IN_RANGE:
+      case UNOP_QUAL:
+	type = elts[pos + 1].type;
+	break;
+
+      default:
+	return operator_check_standard (exp, pos, type_func, objfile_func,
+					data);
+    }
+
+  /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL.  */
+
+  if (type && type_func && (*type_func) (type, data))
+    return 1;
+  if (type && TYPE_OBJFILE (type) && objfile_func
+      && (*objfile_func) (TYPE_OBJFILE (type), data))
+    return 1;
+
+  return 0;
+}
+
 static char *
 ada_op_name (enum exp_opcode opcode)
 {
@@ -11231,6 +11265,7 @@ parse (void)
 static const struct exp_descriptor ada_exp_descriptor = {
   ada_print_subexp,
   ada_operator_length,
+  ada_operator_check,
   ada_op_name,
   ada_dump_subexp_body,
   ada_evaluate_subexp
diff --git a/gdb/block.c b/gdb/block.c
index 1889ecd..e527018 100644
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -317,3 +317,21 @@ allocate_block (struct obstack *obstack)
 
   return bl;
 }
+
+/* Return OBJFILE in which BLOCK is located or NULL if we cannot find it for
+   whatever reason.  */
+
+struct objfile *
+block_objfile (const struct block *block)
+{
+  struct symbol *func;
+
+  if (block == NULL)
+    return NULL;
+
+  func = block_linkage_function (block);
+  if (func == NULL)
+    return NULL;
+
+  return SYMBOL_SYMTAB (func)->objfile;
+}
diff --git a/gdb/block.h b/gdb/block.h
index 53e7371..8290adc 100644
--- a/gdb/block.h
+++ b/gdb/block.h
@@ -166,4 +166,6 @@ extern const struct block *block_global_block (const struct block *block);
 
 extern struct block *allocate_block (struct obstack *obstack);
 
+extern struct objfile *block_objfile (const struct block *block);
+
 #endif /* BLOCK_H */
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index 5718143..f2659bd 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -1101,6 +1101,7 @@ static const struct exp_descriptor exp_descriptor_c =
 {
   print_subexp_standard,
   operator_length_standard,
+  operator_check_standard,
   op_name_standard,
   dump_subexp_body_standard,
   evaluate_subexp_c
diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c
index 27983e7..7fc9d95 100644
--- a/gdb/jv-lang.c
+++ b/gdb/jv-lang.c
@@ -1096,6 +1096,7 @@ const struct exp_descriptor exp_descriptor_java =
 {
   print_subexp_standard,
   operator_length_standard,
+  operator_check_standard,
   op_name_standard,
   dump_subexp_body_standard,
   evaluate_subexp_java
diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
index 85fa123..7095652 100644
--- a/gdb/m2-lang.c
+++ b/gdb/m2-lang.c
@@ -356,6 +356,7 @@ const struct exp_descriptor exp_descriptor_modula2 =
 {
   print_subexp_standard,
   operator_length_standard,
+  operator_check_standard,
   op_name_standard,
   dump_subexp_body_standard,
   evaluate_subexp_modula2
diff --git a/gdb/parse.c b/gdb/parse.c
index de4cd6c..a858290 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -62,6 +62,7 @@ const struct exp_descriptor exp_descriptor_standard =
   {
     print_subexp_standard,
     operator_length_standard,
+    operator_check_standard,
     op_name_standard,
     dump_subexp_body_standard,
     evaluate_subexp_standard
@@ -1359,6 +1360,131 @@ parser_fprintf (FILE *x, const char *y, ...)
   va_end (args);
 }
 
+/* Implementation of the exp_descriptor method operator_check.  */
+
+int
+operator_check_standard (struct expression *exp, int pos,
+			 int (*type_func) (struct type *type, void *data),
+			 int (*objfile_func) (struct objfile *objfile,
+					      void *data),
+			 void *data)
+{
+  const union exp_element *const elts = exp->elts;
+  struct type *type = NULL;
+  struct objfile *objfile = NULL;
+
+  /* Extended operators should have been already handled by exp_descriptor
+     iterate method of its specific language.  */
+  gdb_assert (elts[pos].opcode < OP_EXTENDED0);
+
+  /* Track the callers of write_exp_elt_type for this table.  */
+
+  switch (elts[pos].opcode)
+    {
+    case BINOP_VAL:
+    case OP_COMPLEX:
+    case OP_DECFLOAT:
+    case OP_DOUBLE:
+    case OP_LONG:
+    case OP_SCOPE:
+    case OP_TYPE:
+    case UNOP_CAST:
+    case UNOP_MAX:
+    case UNOP_MEMVAL:
+    case UNOP_MIN:
+      type = elts[pos + 1].type;
+      break;
+
+    case UNOP_MEMVAL_TLS:
+      objfile = elts[pos + 1].objfile;
+      type = elts[pos + 2].type;
+      break;
+
+    case OP_VAR_VALUE:
+      {
+	const struct block *const block = elts[pos + 1].block;
+	const struct symbol *const symbol = elts[pos + 2].symbol;
+	const struct obj_section *const section = SYMBOL_OBJ_SECTION (symbol);
+
+	/* Check objfile where the variable itself is placed.  */
+	if (section && objfile_func && (*objfile_func) (section->objfile, data))
+	  return 1;
+
+	/* Check objfile where is placed the code touching the variable.  */
+	objfile = block_objfile (block);
+
+	type = SYMBOL_TYPE (symbol);
+      }
+      break;
+    }
+
+  /* Invoke callbacks for TYPE and OBJFILE if they were set as non-NULL.  */
+
+  if (type && type_func && (*type_func) (type, data))
+    return 1;
+  if (type && TYPE_OBJFILE (type) && objfile_func
+      && (*objfile_func) (TYPE_OBJFILE (type), data))
+    return 1;
+  if (objfile && objfile_func && (*objfile_func) (objfile, data))
+    return 1;
+
+  return 0;
+}
+
+/* Call TYPE_FUNC and OBJFILE_FUNC for any TYPE and OBJFILE found being
+   referenced by EXP.  The functions are never called with NULL TYPE or NULL
+   OBJFILE.  Functions get passed an arbitrary caller supplied DATA pointer.
+   If any of the functions returns non-zero value then (any other) non-zero
+   value is immediately returned to the caller.  Otherwise zero is returned
+   after iterating through whole EXP.  */
+
+static int
+exp_iterate (struct expression *exp,
+	     int (*type_func) (struct type *type, void *data),
+	     int (*objfile_func) (struct objfile *objfile, void *data),
+	     void *data)
+{
+  int endpos;
+  const union exp_element *const elts = exp->elts;
+
+  for (endpos = exp->nelts; endpos > 0; )
+    {
+      int pos, args, oplen = 0;
+
+      exp->language_defn->la_exp_desc->operator_length (exp, endpos,
+							&oplen, &args);
+      gdb_assert (oplen > 0);
+
+      pos = endpos - oplen;
+      if (exp->language_defn->la_exp_desc->operator_check (exp, pos, type_func,
+							   objfile_func, data))
+	return 1;
+
+      endpos = pos;
+    }
+
+  return 0;
+}
+
+/* Helper for exp_uses_objfile.  */
+
+static int
+exp_uses_objfile_iter (struct objfile *exp_objfile, void *objfile_voidp)
+{
+  struct objfile *objfile = objfile_voidp;
+
+  return exp_objfile == objfile;
+}
+
+/* Return 1 if EXP uses OBJFILE (and will become dangling when OBJFILE
+   is unloaded), otherwise return 0.  */
+
+int
+exp_uses_objfile (struct expression *exp, struct objfile *objfile)
+{
+  return exp_iterate (exp, NULL, exp_uses_objfile_iter, objfile);
+}
+
 void
 _initialize_parse (void)
 {
diff --git a/gdb/parser-defs.h b/gdb/parser-defs.h
index cbda9c3..2791926 100644
--- a/gdb/parser-defs.h
+++ b/gdb/parser-defs.h
@@ -189,6 +189,13 @@ extern void operator_length (struct expression *, int, int *, int *);
 
 extern void operator_length_standard (struct expression *, int, int *, int *);
 
+extern int operator_check_standard (struct expression *exp, int pos,
+				    int (*type_func) (struct type *type,
+						      void *data),
+				    int (*objfile_func)
+				      (struct objfile *objfile, void *data),
+				    void *data);
+
 extern char *op_name_standard (enum exp_opcode);
 
 extern struct type *follow_types (struct type *);
@@ -267,6 +274,20 @@ struct exp_descriptor
        the number of subexpressions it takes.  */
     void (*operator_length) (struct expression*, int, int*, int *);
 
+    /* Call TYPE_FUNC and OBJFILE_FUNC for any TYPE and OBJFILE found being
+       referenced by the single operator of EXP at position POS.  Operator
+       parameters are located at positive (POS + number) offsets in EXP.
+       The functions should never be called with NULL TYPE or NULL OBJFILE.
+       Functions should get passed an arbitrary caller supplied DATA pointer.
+       If any of the functions returns non-zero value then (any other) non-zero
+       value should be immediately returned to the caller.  Otherwise zero
+       should be returned.  */
+    int (*operator_check) (struct expression *exp, int pos,
+			   int (*type_func) (struct type *type, void *data),
+			   int (*objfile_func) (struct objfile *objfile,
+						void *data),
+			   void *data);
+
     /* Name of this operator for dumping purposes.  */
     char *(*op_name) (enum exp_opcode);
 
@@ -299,4 +320,6 @@ extern void print_subexp_standard (struct expression *, int *,
 
 extern void parser_fprintf (FILE *, const char *, ...) ATTR_FORMAT (printf, 2 ,3);
 
+extern int exp_uses_objfile (struct expression *exp, struct objfile *objfile);
+
 #endif /* PARSER_DEFS_H */
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index eeffa6e..3b6c8b5 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -46,7 +46,6 @@
 #include "exceptions.h"
 #include "observer.h"
 #include "solist.h"
-#include "solib.h"
 #include "parser-defs.h"
 #include "charset.h"
 
@@ -1789,50 +1788,6 @@ disable_display_command (char *args, int from_tty)
       }
 }
 
-/* Return 1 if D uses SOLIB (and will become dangling when SOLIB
-   is unloaded), otherwise return 0.  */
-
-static int
-display_uses_solib_p (const struct display *d,
-		      const struct so_list *solib)
-{
-  int endpos;
-  struct expression *const exp = d->exp;
-  const union exp_element *const elts = exp->elts;
-
-  if (d->block != NULL
-      && solib_contains_address_p (solib, d->block->startaddr))
-    return 1;
-
-  for (endpos = exp->nelts; endpos > 0; )
-    {
-      int i, args, oplen = 0;
-
-      exp->language_defn->la_exp_desc->operator_length (exp, endpos,
-							&oplen, &args);
-      gdb_assert (oplen > 0);
-
-      i = endpos - oplen;
-      if (elts[i].opcode == OP_VAR_VALUE)
-	{
-	  const struct block *const block = elts[i + 1].block;
-	  const struct symbol *const symbol = elts[i + 2].symbol;
-	  const struct obj_section *const section =
-	    SYMBOL_OBJ_SECTION (symbol);
-
-	  if (block != NULL
-	      && solib_contains_address_p (solib, block->startaddr))
-	    return 1;
-
-	  if (section && section->objfile == solib->objfile)
-	    return 1;
-	}
-      endpos -= oplen;
-    }
-
-  return 0;
-}
-
 /* display_chain items point to blocks and expressions.  Some expressions in
    turn may point to symbols.
    Both symbols and blocks are obstack_alloc'd on objfile_stack, and are
@@ -1844,18 +1799,26 @@ display_uses_solib_p (const struct display *d,
 static void
 clear_dangling_display_expressions (struct so_list *solib)
 {
+  struct objfile *objfile = solib->objfile;
+  struct objfile *objfile2;
   struct display *d;
-  struct objfile *objfile = NULL;
 
-  for (d = display_chain; d; d = d->next)
-    {
-      if (d->exp && display_uses_solib_p (d, solib))
-	{
-	  xfree (d->exp);
-	  d->exp = NULL;
-	  d->block = NULL;
-	}
-    }
+  /* With no symbol file we cannot have a block or expression from it.  */
+  if (objfile == NULL)
+    return;
+
+  objfile2 = objfile->separate_debug_objfile;
+
+  for (d = display_chain; d != NULL; d = d->next)
+    if (block_objfile (d->block) == objfile
+	|| (d->exp && exp_uses_objfile (d->exp, objfile))
+	|| (objfile2 && (block_objfile (d->block) == objfile2
+	                 || (d->exp && exp_uses_objfile (d->exp, objfile2)))))
+      {
+	xfree (d->exp);
+	d->exp = NULL;
+	d->block = NULL;
+      }
 }
 
 
diff --git a/gdb/scm-lang.c b/gdb/scm-lang.c
index b1d7865..cba0449 100644
--- a/gdb/scm-lang.c
+++ b/gdb/scm-lang.c
@@ -229,6 +229,7 @@ const struct exp_descriptor exp_descriptor_scm =
 {
   print_subexp_standard,
   operator_length_standard,
+  operator_check_standard,
   op_name_standard,
   dump_subexp_body_standard,
   evaluate_exp


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