aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog31
-rw-r--r--gdb/ada-lang.c2
-rw-r--r--gdb/c-lang.c8
-rw-r--r--gdb/f-lang.c2
-rw-r--r--gdb/jv-lang.c2
-rw-r--r--gdb/language.c6
-rw-r--r--gdb/language.h10
-rw-r--r--gdb/m2-lang.c2
-rw-r--r--gdb/objc-lang.c2
-rw-r--r--gdb/p-lang.c2
-rw-r--r--gdb/scm-lang.c2
-rw-r--r--gdb/symtab.c42
-rw-r--r--gdb/testsuite/ChangeLog7
-rw-r--r--gdb/testsuite/gdb.cp/breakpoint.cc29
-rw-r--r--gdb/testsuite/gdb.cp/breakpoint.exp10
-rw-r--r--gdb/valops.c49
-rw-r--r--gdb/value.h2
17 files changed, 134 insertions, 74 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index 60bb3f6..4020069 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -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.
diff --git a/gdb/ada-lang.c b/gdb/ada-lang.c
index 6e829f0..0d38249 100644
--- a/gdb/ada-lang.c
+++ b/gdb/ada-lang.c
@@ -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 */
diff --git a/gdb/c-lang.c b/gdb/c-lang.c
index c4ef9d6..29aa765 100644
--- a/gdb/c-lang.c
+++ b/gdb/c-lang.c
@@ -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 */
diff --git a/gdb/f-lang.c b/gdb/f-lang.c
index 038126c..5dcbd33 100644
--- a/gdb/f-lang.c
+++ b/gdb/f-lang.c
@@ -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 */
diff --git a/gdb/jv-lang.c b/gdb/jv-lang.c
index e6c6f7d..b72b90c 100644
--- a/gdb/jv-lang.c
+++ b/gdb/jv-lang.c
@@ -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 */
diff --git a/gdb/language.c b/gdb/language.c
index a26218d..80f6961 100644
--- a/gdb/language.c
+++ b/gdb/language.c
@@ -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 */
diff --git a/gdb/language.h b/gdb/language.h
index f7e654d..233a5a3 100644
--- a/gdb/language.h
+++ b/gdb/language.h
@@ -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
diff --git a/gdb/m2-lang.c b/gdb/m2-lang.c
index 6b51fd5..bb205ad 100644
--- a/gdb/m2-lang.c
+++ b/gdb/m2-lang.c
@@ -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 */
diff --git a/gdb/objc-lang.c b/gdb/objc-lang.c
index ccf8068..08a6bb8 100644
--- a/gdb/objc-lang.c
+++ b/gdb/objc-lang.c
@@ -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 */
diff --git a/gdb/p-lang.c b/gdb/p-lang.c
index f7b901f..2accf35 100644
--- a/gdb/p-lang.c
+++ b/gdb/p-lang.c
@@ -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 */
diff --git a/gdb/scm-lang.c b/gdb/scm-lang.c
index 339c614..0692d438 100644
--- a/gdb/scm-lang.c
+++ b/gdb/scm-lang.c
@@ -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 */
diff --git a/gdb/symtab.c b/gdb/symtab.c
index aa401ad..6422db4 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -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;
+ }
}
}
diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog
index eac9ba9..c1625b6 100644
--- a/gdb/testsuite/ChangeLog
+++ b/gdb/testsuite/ChangeLog
@@ -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.
diff --git a/gdb/testsuite/gdb.cp/breakpoint.cc b/gdb/testsuite/gdb.cp/breakpoint.cc
index c719af2..98b7891 100644
--- a/gdb/testsuite/gdb.cp/breakpoint.cc
+++ b/gdb/testsuite/gdb.cp/breakpoint.cc
@@ -17,8 +17,26 @@
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;
}
diff --git a/gdb/testsuite/gdb.cp/breakpoint.exp b/gdb/testsuite/gdb.cp/breakpoint.exp
index d75e0f7..57f2fd4 100644
--- a/gdb/testsuite/gdb.cp/breakpoint.exp
+++ b/gdb/testsuite/gdb.cp/breakpoint.exp
@@ -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
diff --git a/gdb/valops.c b/gdb/valops.c
index 882e3a5..b11a088 100644
--- a/gdb/valops.c
+++ b/gdb/valops.c
@@ -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
diff --git a/gdb/value.h b/gdb/value.h
index ba226e5..5f8fe58c0 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -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);