Use bitpos and type to lookup a gdb.Field object when its name is 'None'.
PR python/15464 PR python/16113 * valops.c (value_struct_elt_bitpos): New function * py-type.c (convert_field): Set 'name' attribute of a gdb.Field object to 'None' if the field name is an empty string (""). * python/py-value.c (valpy_getitem): Use 'bitpos' and 'type' attribute to look for a field when 'name' is 'None'. (get_field_type): New function testsuite/ * gdb.python/py-type.c: Enhance test case. * gdb.python/py-value-cc.cc: Likewise * gdb.python/py-type.exp: Add new tests. * gdb.python/py-value-cc.exp: Likewise
This commit is contained in:
parent
13aaf45454
commit
b5b08fb4ff
10 changed files with 208 additions and 18 deletions
|
@ -1,3 +1,14 @@
|
||||||
|
2014-01-13 Siva Chandra Reddy <sivachandra@google.com>
|
||||||
|
|
||||||
|
PR python/15464
|
||||||
|
PR python/16113
|
||||||
|
* valops.c (value_struct_elt_bitpos): New function
|
||||||
|
* py-type.c (convert_field): Set 'name' attribute of a gdb.Field
|
||||||
|
object to 'None' if the field name is an empty string ("").
|
||||||
|
* python/py-value.c (valpy_getitem): Use 'bitpos' and 'type'
|
||||||
|
attribute to look for a field when 'name' is 'None'.
|
||||||
|
(get_field_type): New function
|
||||||
|
|
||||||
2014-01-13 Doug Evans <dje@google.com>
|
2014-01-13 Doug Evans <dje@google.com>
|
||||||
|
|
||||||
PR symtab/16426
|
PR symtab/16426
|
||||||
|
|
|
@ -206,15 +206,22 @@ convert_field (struct type *type, int field)
|
||||||
Py_DECREF (arg);
|
Py_DECREF (arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
arg = NULL;
|
||||||
if (TYPE_FIELD_NAME (type, field))
|
if (TYPE_FIELD_NAME (type, field))
|
||||||
arg = PyString_FromString (TYPE_FIELD_NAME (type, field));
|
{
|
||||||
else
|
const char *field_name = TYPE_FIELD_NAME (type, field);
|
||||||
|
if (field_name[0] != '\0')
|
||||||
|
{
|
||||||
|
arg = PyString_FromString (TYPE_FIELD_NAME (type, field));
|
||||||
|
if (arg == NULL)
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (arg == NULL)
|
||||||
{
|
{
|
||||||
arg = Py_None;
|
arg = Py_None;
|
||||||
Py_INCREF (arg);
|
Py_INCREF (arg);
|
||||||
}
|
}
|
||||||
if (!arg)
|
|
||||||
goto fail;
|
|
||||||
if (PyObject_SetAttrString (result, "name", arg) < 0)
|
if (PyObject_SetAttrString (result, "name", arg) < 0)
|
||||||
goto failarg;
|
goto failarg;
|
||||||
Py_DECREF (arg);
|
Py_DECREF (arg);
|
||||||
|
|
|
@ -563,6 +563,29 @@ get_field_flag (PyObject *field, const char *flag_name)
|
||||||
return flag_value;
|
return flag_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Return the "type" attribute of a gdb.Field object.
|
||||||
|
Returns NULL on error, with a Python exception set. */
|
||||||
|
|
||||||
|
static struct type *
|
||||||
|
get_field_type (PyObject *field)
|
||||||
|
{
|
||||||
|
PyObject *ftype_obj = PyObject_GetAttrString (field, "type");
|
||||||
|
struct type *ftype;
|
||||||
|
|
||||||
|
if (ftype_obj == NULL)
|
||||||
|
return NULL;
|
||||||
|
ftype = type_object_to_type (ftype_obj);
|
||||||
|
Py_DECREF (ftype_obj);
|
||||||
|
if (ftype == NULL)
|
||||||
|
{
|
||||||
|
PyErr_SetString (PyExc_TypeError,
|
||||||
|
_("'type' attribute of gdb.Field object is not a "
|
||||||
|
"gdb.Type object."));
|
||||||
|
}
|
||||||
|
|
||||||
|
return ftype;
|
||||||
|
}
|
||||||
|
|
||||||
/* Given string name or a gdb.Field object corresponding to an element inside
|
/* Given string name or a gdb.Field object corresponding to an element inside
|
||||||
a structure, return its value object. Returns NULL on error, with a python
|
a structure, return its value object. Returns NULL on error, with a python
|
||||||
exception set. */
|
exception set. */
|
||||||
|
@ -572,7 +595,8 @@ valpy_getitem (PyObject *self, PyObject *key)
|
||||||
{
|
{
|
||||||
value_object *self_value = (value_object *) self;
|
value_object *self_value = (value_object *) self;
|
||||||
char *field = NULL;
|
char *field = NULL;
|
||||||
PyObject *base_class_type_object = NULL;
|
struct type *base_class_type = NULL, *field_type = NULL;
|
||||||
|
long bitpos = -1;
|
||||||
volatile struct gdb_exception except;
|
volatile struct gdb_exception except;
|
||||||
PyObject *result = NULL;
|
PyObject *result = NULL;
|
||||||
|
|
||||||
|
@ -603,8 +627,8 @@ valpy_getitem (PyObject *self, PyObject *key)
|
||||||
return NULL;
|
return NULL;
|
||||||
else if (is_base_class > 0)
|
else if (is_base_class > 0)
|
||||||
{
|
{
|
||||||
base_class_type_object = PyObject_GetAttrString (key, "type");
|
base_class_type = get_field_type (key);
|
||||||
if (base_class_type_object == NULL)
|
if (base_class_type == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -614,10 +638,40 @@ valpy_getitem (PyObject *self, PyObject *key)
|
||||||
if (name_obj == NULL)
|
if (name_obj == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
field = python_string_to_host_string (name_obj);
|
if (name_obj != Py_None)
|
||||||
Py_DECREF (name_obj);
|
{
|
||||||
if (field == NULL)
|
field = python_string_to_host_string (name_obj);
|
||||||
return NULL;
|
Py_DECREF (name_obj);
|
||||||
|
if (field == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
PyObject *bitpos_obj;
|
||||||
|
int valid;
|
||||||
|
|
||||||
|
Py_DECREF (name_obj);
|
||||||
|
|
||||||
|
if (!PyObject_HasAttrString (key, "bitpos"))
|
||||||
|
{
|
||||||
|
PyErr_SetString (PyExc_AttributeError,
|
||||||
|
_("gdb.Field object has no name and no "
|
||||||
|
"'bitpos' attribute."));
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
bitpos_obj = PyObject_GetAttrString (key, "bitpos");
|
||||||
|
if (bitpos_obj == NULL)
|
||||||
|
return NULL;
|
||||||
|
valid = gdb_py_int_as_long (bitpos_obj, &bitpos);
|
||||||
|
Py_DECREF (bitpos_obj);
|
||||||
|
if (!valid)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
field_type = get_field_type (key);
|
||||||
|
if (field_type == NULL)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -629,14 +683,12 @@ valpy_getitem (PyObject *self, PyObject *key)
|
||||||
|
|
||||||
if (field)
|
if (field)
|
||||||
res_val = value_struct_elt (&tmp, NULL, field, 0, NULL);
|
res_val = value_struct_elt (&tmp, NULL, field, 0, NULL);
|
||||||
else if (base_class_type_object != NULL)
|
else if (bitpos >= 0)
|
||||||
|
res_val = value_struct_elt_bitpos (&tmp, bitpos, field_type,
|
||||||
|
"struct/class/union");
|
||||||
|
else if (base_class_type != NULL)
|
||||||
{
|
{
|
||||||
struct type *base_class_type, *val_type;
|
struct type *val_type;
|
||||||
|
|
||||||
base_class_type = type_object_to_type (base_class_type_object);
|
|
||||||
Py_DECREF (base_class_type_object);
|
|
||||||
if (base_class_type == NULL)
|
|
||||||
error (_("Field type not an instance of gdb.Type."));
|
|
||||||
|
|
||||||
val_type = check_typedef (value_type (tmp));
|
val_type = check_typedef (value_type (tmp));
|
||||||
if (TYPE_CODE (val_type) == TYPE_CODE_PTR)
|
if (TYPE_CODE (val_type) == TYPE_CODE_PTR)
|
||||||
|
|
|
@ -1,3 +1,12 @@
|
||||||
|
2014-01-13 Siva Chandra Reddy <sivachandra@google.com>
|
||||||
|
|
||||||
|
PR python/15464
|
||||||
|
PR python/16113
|
||||||
|
* gdb.python/py-type.c: Enhance test case.
|
||||||
|
* gdb.python/py-value-cc.cc: Likewise
|
||||||
|
* gdb.python/py-type.exp: Add new tests.
|
||||||
|
* gdb.python/py-value-cc.exp: Likewise
|
||||||
|
|
||||||
2014-01-10 Andreas Arnez <arnez@linux.vnet.ibm.com>
|
2014-01-10 Andreas Arnez <arnez@linux.vnet.ibm.com>
|
||||||
Pedro Alves <palves@redhat.com>
|
Pedro Alves <palves@redhat.com>
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,12 @@ struct s
|
||||||
int b;
|
int b;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SS
|
||||||
|
{
|
||||||
|
union { int x; char y; };
|
||||||
|
union { int a; char b; };
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct s TS;
|
typedef struct s TS;
|
||||||
TS ts;
|
TS ts;
|
||||||
|
|
||||||
|
@ -58,6 +64,7 @@ main ()
|
||||||
{
|
{
|
||||||
int ar[2] = {1,2};
|
int ar[2] = {1,2};
|
||||||
struct s st;
|
struct s st;
|
||||||
|
struct SS ss;
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
C c;
|
C c;
|
||||||
c.c = 1;
|
c.c = 1;
|
||||||
|
@ -72,6 +79,8 @@ main ()
|
||||||
st.b = 5;
|
st.b = 5;
|
||||||
|
|
||||||
e = v2;
|
e = v2;
|
||||||
|
|
||||||
|
ss.x = 100;
|
||||||
|
|
||||||
return 0; /* break to inspect struct and array. */
|
return 0; /* break to inspect struct and array. */
|
||||||
}
|
}
|
||||||
|
|
|
@ -85,6 +85,15 @@ proc test_fields {lang} {
|
||||||
gdb_test "python print (fields\[0\].name)" "a" "Check structure field a name"
|
gdb_test "python print (fields\[0\].name)" "a" "Check structure field a name"
|
||||||
gdb_test "python print (fields\[1\].name)" "b" "Check structure field b name"
|
gdb_test "python print (fields\[1\].name)" "b" "Check structure field b name"
|
||||||
|
|
||||||
|
# Test that unamed fields have 'None' for name.
|
||||||
|
gdb_py_test_silent_cmd "python ss = gdb.parse_and_eval('ss')" "init ss" 1
|
||||||
|
gdb_py_test_silent_cmd "python ss_fields = ss.type.fields()" \
|
||||||
|
"get fields from ss.type" 1
|
||||||
|
gdb_test "python print len(ss_fields)" "2" "Check length of ss_fields"
|
||||||
|
gdb_test "python print ss_fields\[0\].name is None" "True" \
|
||||||
|
"Check ss_fields\[0\].name"
|
||||||
|
gdb_test "python print ss_fields\[1\].name is None" "True" \
|
||||||
|
"Check ss_fields\[1\].name"
|
||||||
# Regression test for
|
# Regression test for
|
||||||
# http://sourceware.org/bugzilla/show_bug.cgi?id=12070.
|
# http://sourceware.org/bugzilla/show_bug.cgi?id=12070.
|
||||||
gdb_test "python print ('type' in dir(fields\[0\]))" "True" \
|
gdb_test "python print ('type' in dir(fields\[0\]))" "True" \
|
||||||
|
|
|
@ -30,8 +30,21 @@ class B : public A {
|
||||||
char a;
|
char a;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct X
|
||||||
|
{
|
||||||
|
union { int x; char y; };
|
||||||
|
union { int a; char b; };
|
||||||
|
};
|
||||||
|
|
||||||
|
union UU
|
||||||
|
{
|
||||||
|
union { int x; char y; };
|
||||||
|
union { int a; char b; };
|
||||||
|
};
|
||||||
|
|
||||||
typedef B Btd;
|
typedef B Btd;
|
||||||
typedef int *int_ptr;
|
typedef int *int_ptr;
|
||||||
|
typedef X Xtd;
|
||||||
|
|
||||||
int
|
int
|
||||||
func (const A &a)
|
func (const A &a)
|
||||||
|
@ -57,6 +70,16 @@ func (const A &a)
|
||||||
U u;
|
U u;
|
||||||
u.a = 99;
|
u.a = 99;
|
||||||
|
|
||||||
|
X x;
|
||||||
|
x.x = 101;
|
||||||
|
x.a = 102;
|
||||||
|
|
||||||
|
UU uu;
|
||||||
|
uu.x = 1000;
|
||||||
|
|
||||||
|
X *x_ptr = &x;
|
||||||
|
Xtd *xtd = &x;
|
||||||
|
|
||||||
return 0; /* Break here. */
|
return 0; /* Break here. */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,14 @@ gdb_test_no_output "python b_ref = gdb.parse_and_eval('b_ref')" "init b_ref"
|
||||||
gdb_test_no_output "python b_td = gdb.parse_and_eval('b_td')" "init b_td"
|
gdb_test_no_output "python b_td = gdb.parse_and_eval('b_td')" "init b_td"
|
||||||
gdb_test_no_output "python u = gdb.parse_and_eval('u')" "init u"
|
gdb_test_no_output "python u = gdb.parse_and_eval('u')" "init u"
|
||||||
gdb_test_no_output "python u_fields = u.type.fields()" "init u_fields"
|
gdb_test_no_output "python u_fields = u.type.fields()" "init u_fields"
|
||||||
|
gdb_test_no_output "python x = gdb.parse_and_eval('x')" "init x"
|
||||||
|
gdb_test_no_output "python x_fields = x.type.fields()" "init x_fields"
|
||||||
|
gdb_test_no_output "python uu = gdb.parse_and_eval('uu')" "init uu"
|
||||||
|
gdb_test_no_output "python uu_fields = uu.type.fields()" "init uu_fields"
|
||||||
|
gdb_test_no_output "python x_ptr = gdb.parse_and_eval('x_ptr')" "init x_ptr"
|
||||||
|
gdb_test_no_output "python xtd = gdb.parse_and_eval('xtd')" "init xtd"
|
||||||
|
|
||||||
|
gdb_test "python print(b\[b_fields\[1\]\])" "97 'a'" "b.a via field"
|
||||||
|
|
||||||
gdb_test "python print(b\[b_fields\[1\]\])" "97 'a'" "b.a via field"
|
gdb_test "python print(b\[b_fields\[1\]\])" "97 'a'" "b.a via field"
|
||||||
gdb_test "python print(b\[b_fields\[0\]\].type)" "A" \
|
gdb_test "python print(b\[b_fields\[0\]\].type)" "A" \
|
||||||
|
@ -79,3 +87,15 @@ gdb_test "python print(b_td\[b_fields\[0\]\]\['a'\])" "100" \
|
||||||
|
|
||||||
gdb_test "python print(u\[u_fields\[0\]\])" "99.*" "u's first field via field"
|
gdb_test "python print(u\[u_fields\[0\]\])" "99.*" "u's first field via field"
|
||||||
gdb_test "python print(u\[u_fields\[1\]\])" "99.*" "u's second field via field"
|
gdb_test "python print(u\[u_fields\[1\]\])" "99.*" "u's second field via field"
|
||||||
|
|
||||||
|
gdb_test "python print len(x_fields)" "2" "number for fields in u"
|
||||||
|
gdb_test "python print x\[x_fields\[0\]\]\['x'\]" "101" "x.x via field"
|
||||||
|
gdb_test "python print x\[x_fields\[1\]\]\['a'\]" "102" "x.a via field"
|
||||||
|
gdb_test "python print x_ptr\[x_fields\[0\]\]\['x'\]" "101" "x_ptr->x via field"
|
||||||
|
gdb_test "python print x_ptr\[x_fields\[1\]\]\['a'\]" "102" "x_ptr->a via field"
|
||||||
|
gdb_test "python print xtd\[x_fields\[0\]\]\['x'\]" "101" "xtd->x via field"
|
||||||
|
gdb_test "python print xtd\[x_fields\[1\]\]\['a'\]" "102" "xtd->a via field"
|
||||||
|
|
||||||
|
gdb_test "python print len(uu_fields)" "2" "number of fields in uu"
|
||||||
|
gdb_test "python print uu\[uu_fields\[0\]\]\['x'\]" "1000" "uu.x via field"
|
||||||
|
gdb_test "python print uu\[uu_fields\[1\]\]\['a'\]" "1000" "uu.a via field"
|
||||||
|
|
45
gdb/valops.c
45
gdb/valops.c
|
@ -2246,6 +2246,51 @@ value_struct_elt (struct value **argp, struct value **args,
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Given *ARGP, a value of type structure or union, or a pointer/reference
|
||||||
|
to a structure or union, extract and return its component (field) of
|
||||||
|
type FTYPE at the specified BITPOS.
|
||||||
|
Throw an exception on error. */
|
||||||
|
|
||||||
|
struct value *
|
||||||
|
value_struct_elt_bitpos (struct value **argp, int bitpos, struct type *ftype,
|
||||||
|
const char *err)
|
||||||
|
{
|
||||||
|
struct type *t;
|
||||||
|
struct value *v;
|
||||||
|
int i;
|
||||||
|
int nbases;
|
||||||
|
|
||||||
|
*argp = coerce_array (*argp);
|
||||||
|
|
||||||
|
t = check_typedef (value_type (*argp));
|
||||||
|
|
||||||
|
while (TYPE_CODE (t) == TYPE_CODE_PTR || TYPE_CODE (t) == TYPE_CODE_REF)
|
||||||
|
{
|
||||||
|
*argp = value_ind (*argp);
|
||||||
|
if (TYPE_CODE (check_typedef (value_type (*argp))) != TYPE_CODE_FUNC)
|
||||||
|
*argp = coerce_array (*argp);
|
||||||
|
t = check_typedef (value_type (*argp));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (TYPE_CODE (t) != TYPE_CODE_STRUCT
|
||||||
|
&& TYPE_CODE (t) != TYPE_CODE_UNION)
|
||||||
|
error (_("Attempt to extract a component of a value that is not a %s."),
|
||||||
|
err);
|
||||||
|
|
||||||
|
for (i = TYPE_N_BASECLASSES (t); i < TYPE_NFIELDS (t); i++)
|
||||||
|
{
|
||||||
|
if (!field_is_static (&TYPE_FIELD (t, i))
|
||||||
|
&& bitpos == TYPE_FIELD_BITPOS (t, i)
|
||||||
|
&& types_equal (ftype, TYPE_FIELD_TYPE (t, i)))
|
||||||
|
return value_primitive_field (*argp, 0, i, t);
|
||||||
|
}
|
||||||
|
|
||||||
|
error (_("No field with matching bitpos and type."));
|
||||||
|
|
||||||
|
/* Never hit. */
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* Search through the methods of an object (and its bases) to find a
|
/* Search through the methods of an object (and its bases) to find a
|
||||||
specified method. Return the pointer to the fn_field list of
|
specified method. Return the pointer to the fn_field list of
|
||||||
overloaded instances.
|
overloaded instances.
|
||||||
|
|
|
@ -670,6 +670,11 @@ extern struct value *value_struct_elt (struct value **argp,
|
||||||
const char *name, int *static_memfuncp,
|
const char *name, int *static_memfuncp,
|
||||||
const char *err);
|
const char *err);
|
||||||
|
|
||||||
|
extern struct value *value_struct_elt_bitpos (struct value **argp,
|
||||||
|
int bitpos,
|
||||||
|
struct type *field_type,
|
||||||
|
const char *err);
|
||||||
|
|
||||||
extern struct value *value_aggregate_elt (struct type *curtype,
|
extern struct value *value_aggregate_elt (struct type *curtype,
|
||||||
char *name,
|
char *name,
|
||||||
struct type *expect_type,
|
struct type *expect_type,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue