Fix breakpoint condition that use member variables.
authorVladimir Prus <vladimir@codesourcery.com>
Sun, 6 Apr 2008 08:56:37 +0000 (08:56 +0000)
committerVladimir Prus <vladimir@codesourcery.com>
Sun, 6 Apr 2008 08:56:37 +0000 (08:56 +0000)
        * valops.c (check_field): Remove.
        (check_field_in): Rename to check_field.
        (value_of_this): Use la_name_of_this.
        * value.h (check_field): Adjust prototype.

        * language.h (la_value_of_this): Rename to la_name_of_this.
        * language.c (unknown_language_defn): Specify "this" for
        name_of_this.
        (auto_language_defn): Likewise.
        (local_language_defn): Likewise.
        * ada-lang.c (ada_language_defn): Adjust comment.
        * c-lang.c (c_language_defn): Adjust comment.
        (cplus_language_defn): Specify "this" for name_of_this.
        (asm_language_defn): Adjust comment.
        (minimal_language_defn): Adjust comment.
        * f-lang.c (f_language_defn): Specify NULL for name_of_this.
        * jv-lang.c (java_language_defn): Specify "this" for name_of_this.
        * m2-lang.c (m2_language_defn): Specify "this" for name_of_this.
        * objc-lang.c (objc_language_defn): Specify "self" for
        name_of_this.
        * p-lang.c (pascal_language_defn): Specify "this" for
        name_of_this.
        * scm-lang.c (scm_language_defn): Specify NULL for name_of_this.

        * symtab.c (lookup_symbol_aux): Lookup "this" in the
        proper scope, and check for field in type of "this", without
        trying to create a value.

17 files changed:
gdb/ChangeLog
gdb/ada-lang.c
gdb/c-lang.c
gdb/f-lang.c
gdb/jv-lang.c
gdb/language.c
gdb/language.h
gdb/m2-lang.c
gdb/objc-lang.c
gdb/p-lang.c
gdb/scm-lang.c
gdb/symtab.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.cp/breakpoint.cc
gdb/testsuite/gdb.cp/breakpoint.exp
gdb/valops.c
gdb/value.h

index 60bb3f6..4020069 100644 (file)
@@ -1,3 +1,34 @@
+2008-04-06  Vladimir Prus  <vladimir@codesourcery.com>
+
+       Fix breakpoint condition that use member variables.
+        * valops.c (check_field): Remove.
+        (check_field_in): Rename to check_field.
+        (value_of_this): Use la_name_of_this.
+        * value.h (check_field): Adjust prototype.
+
+        * language.h (la_value_of_this): Rename to la_name_of_this.
+        * language.c (unknown_language_defn): Specify "this" for
+        name_of_this.
+        (auto_language_defn): Likewise.
+        (local_language_defn): Likewise.
+        * ada-lang.c (ada_language_defn): Adjust comment.
+        * c-lang.c (c_language_defn): Adjust comment.
+        (cplus_language_defn): Specify "this" for name_of_this.
+        (asm_language_defn): Adjust comment.
+        (minimal_language_defn): Adjust comment.
+        * f-lang.c (f_language_defn): Specify NULL for name_of_this.
+        * jv-lang.c (java_language_defn): Specify "this" for name_of_this.
+        * m2-lang.c (m2_language_defn): Specify "this" for name_of_this.
+        * objc-lang.c (objc_language_defn): Specify "self" for
+        name_of_this.
+        * p-lang.c (pascal_language_defn): Specify "this" for
+        name_of_this.
+        * scm-lang.c (scm_language_defn): Specify NULL for name_of_this.
+
+        * symtab.c (lookup_symbol_aux): Lookup "this" in the
+        proper scope, and check for field in type of "this", without
+        trying to create a value.
+
 2008-04-04  Pedro Alves  <pedro@codesourcery.com>
 
        * mi/mi-cmds.h (enum mi_cmd_result): Delete MI_CMD_ERROR.
index 6e829f0..0d38249 100644 (file)
@@ -11011,7 +11011,7 @@ const struct language_defn ada_language_defn = {
   ada_val_print,                /* Print a value using appropriate syntax */
   ada_value_print,              /* Print a top-level value */
   NULL,                         /* Language specific skip_trampoline */
-  NULL,                         /* value_of_this */
+  NULL,                         /* name_of_this */
   ada_lookup_symbol_nonlocal,   /* Looking up non-local symbols.  */
   basic_lookup_transparent_type,        /* lookup_transparent_type */
   ada_la_decode,                /* Language specific symbol demangler */
index c4ef9d6..29aa765 100644 (file)
@@ -414,7 +414,7 @@ const struct language_defn c_language_defn =
   c_val_print,                 /* Print a value using appropriate syntax */
   c_value_print,               /* Print a top-level value */
   NULL,                                /* Language specific skip_trampoline */
-  NULL,                                /* value_of_this */
+  NULL,                                /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
@@ -527,7 +527,7 @@ const struct language_defn cplus_language_defn =
   c_val_print,                 /* Print a value using appropriate syntax */
   c_value_print,               /* Print a top-level value */
   cplus_skip_trampoline,       /* Language specific skip_trampoline */
-  value_of_this,               /* value_of_this */
+  "this",                       /* name_of_this */
   cp_lookup_symbol_nonlocal,   /* lookup_symbol_nonlocal */
   cp_lookup_transparent_type,   /* lookup_transparent_type */
   cplus_demangle,              /* Language specific symbol demangler */
@@ -562,7 +562,7 @@ const struct language_defn asm_language_defn =
   c_val_print,                 /* Print a value using appropriate syntax */
   c_value_print,               /* Print a top-level value */
   NULL,                                /* Language specific skip_trampoline */
-  NULL,                                /* value_of_this */
+  NULL,                                /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
@@ -602,7 +602,7 @@ const struct language_defn minimal_language_defn =
   c_val_print,                 /* Print a value using appropriate syntax */
   c_value_print,               /* Print a top-level value */
   NULL,                                /* Language specific skip_trampoline */
-  NULL,                                /* value_of_this */
+  NULL,                                /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
index 038126c..5dcbd33 100644 (file)
@@ -324,7 +324,7 @@ const struct language_defn f_language_defn =
   f_val_print,                 /* Print a value using appropriate syntax */
   c_value_print,               /* FIXME */
   NULL,                                /* Language specific skip_trampoline */
-  value_of_this,               /* value_of_this */
+  NULL,                        /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
index e6c6f7d..b72b90c 100644 (file)
@@ -1070,7 +1070,7 @@ const struct language_defn java_language_defn =
   java_val_print,              /* Print a value using appropriate syntax */
   java_value_print,            /* Print a top-level value */
   NULL,                                /* Language specific skip_trampoline */
-  value_of_this,               /* value_of_this */
+  "this",                      /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   java_demangle,               /* Language specific symbol demangler */
index a26218d..80f6961 100644 (file)
@@ -1192,7 +1192,7 @@ const struct language_defn unknown_language_defn =
   unk_lang_val_print,          /* Print a value using appropriate syntax */
   unk_lang_value_print,                /* Print a top-level value */
   unk_lang_trampoline,         /* Language specific skip_trampoline */
-  value_of_this,               /* value_of_this */
+  "this",                      /* name_of_this */
   basic_lookup_symbol_nonlocal, /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   unk_lang_demangle,           /* Language specific symbol demangler */
@@ -1228,7 +1228,7 @@ const struct language_defn auto_language_defn =
   unk_lang_val_print,          /* Print a value using appropriate syntax */
   unk_lang_value_print,                /* Print a top-level value */
   unk_lang_trampoline,         /* Language specific skip_trampoline */
-  value_of_this,               /* value_of_this */
+  "this",                      /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   unk_lang_demangle,           /* Language specific symbol demangler */
@@ -1263,7 +1263,7 @@ const struct language_defn local_language_defn =
   unk_lang_val_print,          /* Print a value using appropriate syntax */
   unk_lang_value_print,                /* Print a top-level value */
   unk_lang_trampoline,         /* Language specific skip_trampoline */
-  value_of_this,               /* value_of_this */
+  "this",                      /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   unk_lang_demangle,           /* Language specific symbol demangler */
index f7e654d..233a5a3 100644 (file)
@@ -206,14 +206,10 @@ struct language_defn
 
     /* Now come some hooks for lookup_symbol.  */
 
-    /* If this is non-NULL, lookup_symbol will do the 'field_of_this'
-       check, using this function to find the value of this.  */
+    /* If this is non-NULL, specifies the name that of the implicit
+       local variable that refers to the current object instance.  */
 
-    /* FIXME: carlton/2003-05-19: Audit all the language_defn structs
-       to make sure we're setting this appropriately: I'm sure it
-       could be NULL in more languages.  */
-
-    struct value *(*la_value_of_this) (int complain);
+    char *la_name_of_this;
 
     /* This is a function that lookup_symbol will call when it gets to
        the part of symbol lookup where C looks up static and global
index 6b51fd5..bb205ad 100644 (file)
@@ -375,7 +375,7 @@ const struct language_defn m2_language_defn =
   m2_val_print,                        /* Print a value using appropriate syntax */
   c_value_print,               /* Print a top-level value */
   NULL,                                /* Language specific skip_trampoline */
-  value_of_this,               /* value_of_this */
+  NULL,                                /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
index ccf8068..08a6bb8 100644 (file)
@@ -509,7 +509,7 @@ const struct language_defn objc_language_defn = {
   c_val_print,                 /* Print a value using appropriate syntax */
   c_value_print,               /* Print a top-level value */
   objc_skip_trampoline,        /* Language specific skip_trampoline */
-  value_of_this,               /* value_of_this */
+  "self",                      /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   objc_demangle,               /* Language specific symbol demangler */
index f7b901f..2accf35 100644 (file)
@@ -414,7 +414,7 @@ const struct language_defn pascal_language_defn =
   pascal_val_print,            /* Print a value using appropriate syntax */
   pascal_value_print,          /* Print a top-level value */
   NULL,                                /* Language specific skip_trampoline */
-  value_of_this,               /* value_of_this */
+  "this",                      /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
index 339c614..0692d43 100644 (file)
@@ -253,7 +253,7 @@ const struct language_defn scm_language_defn =
   scm_val_print,               /* Print a value using appropriate syntax */
   scm_value_print,             /* Print a top-level value */
   NULL,                                /* Language specific skip_trampoline */
-  value_of_this,               /* value_of_this */
+  NULL,                                /* name_of_this */
   basic_lookup_symbol_nonlocal,        /* lookup_symbol_nonlocal */
   basic_lookup_transparent_type,/* lookup_transparent_type */
   NULL,                                /* Language specific symbol demangler */
index aa401ad..6422db4 100644 (file)
@@ -1222,17 +1222,41 @@ lookup_symbol_aux (const char *name, const char *linkage_name,
 
   langdef = language_def (language);
 
-  if (langdef->la_value_of_this != NULL
-      && is_a_field_of_this != NULL)
+  if (langdef->la_name_of_this != NULL && is_a_field_of_this != NULL
+      && block != NULL)
     {
-      struct value *v = langdef->la_value_of_this (0);
-
-      if (v && check_field (v, name))
+      struct symbol *sym = NULL;
+      /* 'this' is only defined in the function's block, so find the
+        enclosing function block.  */
+      for (; block && !BLOCK_FUNCTION (block); 
+          block = BLOCK_SUPERBLOCK (block));
+
+      if (block && !dict_empty (BLOCK_DICT (block)))
+       sym = lookup_block_symbol (block, langdef->la_name_of_this,
+                                  NULL, VAR_DOMAIN);
+      if (sym)
        {
-         *is_a_field_of_this = 1;
-         if (symtab != NULL)
-           *symtab = NULL;
-         return NULL;
+         struct type *t = sym->type;
+         
+         /* I'm not really sure that type of this can ever
+            be typedefed; just be safe.  */
+         CHECK_TYPEDEF (t);
+         if (TYPE_CODE (t) == TYPE_CODE_PTR
+             || TYPE_CODE (t) == TYPE_CODE_REF)
+           t = TYPE_TARGET_TYPE (t);
+         
+         if (TYPE_CODE (t) != TYPE_CODE_STRUCT
+             && TYPE_CODE (t) != TYPE_CODE_UNION)
+           error (_("Internal error: `%s' is not an aggregate"), 
+                  langdef->la_name_of_this);
+         
+         if (check_field (t, name))
+           {
+             *is_a_field_of_this = 1;
+             if (symtab != NULL)
+               *symtab = NULL;
+             return NULL;
+           }
        }
     }
 
index eac9ba9..c1625b6 100644 (file)
@@ -1,3 +1,10 @@
+2008-04-06  Vladimir Prus  <vladimir@codesourcery.com>
+
+        * gdb.cp/breakpoint.cc: New code to test conditions involving
+        member variables.
+        * gdb.cp/breakpoint.exp: Test condition involving member
+        variables.
+
 2008-04-05  Vladimir Prus  <vladimir@codesourcery.com>
 
        * lib/mi-support.exp (mi_expect_stop): New.
index c719af2..98b7891 100644 (file)
    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
 
+int g = 0;
+
 class C1 {
 public:
+  C1(int i) : i_(i) {}
+
+  int foo ()
+  {
+    return 1; // conditional breakpoint in method
+  }
+
+  int bar ()
+  {
+    for (int i = 0; i < 1; ++i)
+      {
+       int t = i * 2;
+       g += t; // conditional breakpoint in method 2
+      }
+  }
+
   class Nested {
   public:
     int
@@ -27,13 +45,22 @@ public:
       return 1;
     }
   };
+
+private:
+  int i_;
 };
 
 int main ()
 {
   C1::Nested c1;
 
-  c1.foo();
+  c1.foo ();
+  
+  C1 c2 (2), c3 (3);
+  c2.foo ();
+  c2.bar ();
+  c3.foo ();
+  c3.bar ();
 
   return 0;
 }
index d75e0f7..57f2fd4 100644 (file)
@@ -61,5 +61,15 @@ proc test_breakpoint {name} {
 
 test_breakpoint "C1::Nested::foo"
 
+set bp_location1 [gdb_get_line_number "conditional breakpoint in method"]
+set bp_location2 [gdb_get_line_number "conditional breakpoint in method 2"]
+gdb_test "break $bp_location1 if i_==3" ".*Breakpoint.*" "conditional breakpoint in method"
+gdb_test "break $bp_location2 if i_==3" ".*Breakpoint.*" "conditional breakpoint in method 2"
+gdb_test "continue" ".*Breakpoint.*C1::foo.*" "continue to breakpoint"
+gdb_test "print i_" "\\\$1 = 3" "check the member variable"
+gdb_test "continue" ".*Breakpoint.*C1::bar.*" "continue to breakpoint"
+gdb_test "print i_" "\\\$2 = 3" "check the member variable"
+
+
 gdb_exit
 return 0
index 882e3a5..b11a088 100644 (file)
@@ -80,8 +80,6 @@ static enum
 oload_classification classify_oload_match (struct badness_vector *,
                                           int, int);
 
-static int check_field_in (struct type *, const char *);
-
 static struct value *value_struct_elt_for_reference (struct type *,
                                                     int, struct type *,
                                                     char *,
@@ -2338,12 +2336,12 @@ destructor_name_p (const char *name, const struct type *type)
   return 0;
 }
 
-/* Helper function for check_field: Given TYPE, a structure/union,
+/* Given TYPE, a structure/union,
    return 1 if the component named NAME from the ultimate target
    structure/union is defined, otherwise, return 0.  */
 
-static int
-check_field_in (struct type *type, const char *name)
+int
+check_field (struct type *type, const char *name)
 {
   int i;
 
@@ -2372,44 +2370,12 @@ check_field_in (struct type *type, const char *name)
     }
 
   for (i = TYPE_N_BASECLASSES (type) - 1; i >= 0; i--)
-    if (check_field_in (TYPE_BASECLASS (type, i), name))
+    if (check_field (TYPE_BASECLASS (type, i), name))
       return 1;
 
   return 0;
 }
 
-
-/* C++: Given ARG1, a value of type (pointer to a)* structure/union,
-   return 1 if the component named NAME from the ultimate target
-   structure/union is defined, otherwise, return 0.  */
-
-int
-check_field (struct value *arg1, const char *name)
-{
-  struct type *t;
-
-  arg1 = coerce_array (arg1);
-
-  t = value_type (arg1);
-
-  /* Follow pointers until we get to a non-pointer.  */
-
-  for (;;)
-    {
-      CHECK_TYPEDEF (t);
-      if (TYPE_CODE (t) != TYPE_CODE_PTR 
-         && TYPE_CODE (t) != TYPE_CODE_REF)
-       break;
-      t = TYPE_TARGET_TYPE (t);
-    }
-
-  if (TYPE_CODE (t) != TYPE_CODE_STRUCT
-      && TYPE_CODE (t) != TYPE_CODE_UNION)
-    error (_("Internal error: `this' is not an aggregate"));
-
-  return check_field_in (t, name);
-}
-
 /* C++: Given an aggregate type CURTYPE, and a member name NAME,
    return the appropriate member (or the address of the member, if
    WANT_ADDRESS).  This function is used to resolve user expressions
@@ -2815,10 +2781,9 @@ value_of_local (const char *name, int complain)
 struct value *
 value_of_this (int complain)
 {
-  if (current_language->la_language == language_objc)
-    return value_of_local ("self", complain);
-  else
-    return value_of_local ("this", complain);
+  if (!current_language->la_name_of_this)
+    return 0;
+  return value_of_local (current_language->la_name_of_this, complain);
 }
 
 /* Create a slice (sub-string, sub-array) of ARRAY, that is LENGTH
index ba226e5..5f8fe58 100644 (file)
@@ -530,7 +530,7 @@ extern void print_variable_value (struct symbol *var,
                                  struct frame_info *frame,
                                  struct ui_file *stream);
 
-extern int check_field (struct value *, const char *);
+extern int check_field (struct type *, const char *);
 
 extern void typedef_print (struct type *type, struct symbol *news,
                           struct ui_file *stream);