Support rvalue references in the gdb python module (includes doc/)

This patch adds the ability to inspect rvalue reference types and values using
the gdb python module. This is achieved by creating two wrappers for
valpy_reference_value(), using the ReferenceExplorer class to handle the
objects of rvalue reference types and placing necessary checks for a
TYPE_CODE_RVALUE_REF type code next to the checks for a TYPE_CODE_REF type
code.

gdb/ChangeLog

	PR gdb/14441
	* doc/python.texi (Types in Python): Add TYPE_CODE_RVALUE_REF to
	table of constants.
	* python/lib/gdb/command/explore.py: Support exploring values
	of rvalue reference types.
	* python/lib/gdb/types.py: Implement get_basic_type() for
	rvalue reference types.
	* python/py-type.c (pyty_codes) <TYPE_CODE_RVALUE_REF>: New
	constant.
	* python/py-value.c (valpy_getitem): Add an rvalue reference
	check.
	(valpy_reference_value): Add new parameter "refcode".
	(valpy_lvalue_reference_value, valpy_rvalue_reference_value):
	New wrappers for valpy_reference_value().
	* python/py-xmethods.c (gdbpy_get_xmethod_result_type)
	(gdbpy_invoke_xmethod): Likewise.
This commit is contained in:
Artemiy Volkov 2017-03-20 13:47:52 -07:00 committed by Keith Seitz
parent 4297a3f002
commit 3fcf899da1
7 changed files with 52 additions and 9 deletions

View File

@ -1,3 +1,22 @@
2017-03-20 Artemiy Volkov <artemiyv@acm.org>
PR gdb/14441
* doc/python.texi (Types in Python): Add TYPE_CODE_RVALUE_REF to
table of constants.
* python/lib/gdb/command/explore.py: Support exploring values
of rvalue reference types.
* python/lib/gdb/types.py: Implement get_basic_type() for
rvalue reference types.
* python/py-type.c (pyty_codes) <TYPE_CODE_RVALUE_REF>: New
constant.
* python/py-value.c (valpy_getitem): Add an rvalue reference
check.
(valpy_reference_value): Add new parameter "refcode".
(valpy_lvalue_reference_value, valpy_rvalue_reference_value):
New wrappers for valpy_reference_value().
* python/py-xmethods.c (gdbpy_get_xmethod_result_type)
(gdbpy_invoke_xmethod): Likewise.
2017-03-20 Artemiy Volkov <artemiyv@acm.org> 2017-03-20 Artemiy Volkov <artemiyv@acm.org>
PR gdb/14441 PR gdb/14441

View File

@ -1162,6 +1162,10 @@ A pointer-to-member.
@item gdb.TYPE_CODE_REF @item gdb.TYPE_CODE_REF
A reference type. A reference type.
@vindex TYPE_CODE_RVALUE_REF
@item gdb.TYPE_CODE_RVALUE_REF
A C@t{++}11 rvalue reference type.
@vindex TYPE_CODE_CHAR @vindex TYPE_CODE_CHAR
@item gdb.TYPE_CODE_CHAR @item gdb.TYPE_CODE_CHAR
A character type. A character type.

View File

@ -132,6 +132,7 @@ class Explorer(object):
gdb.TYPE_CODE_UNION : CompoundExplorer, gdb.TYPE_CODE_UNION : CompoundExplorer,
gdb.TYPE_CODE_PTR : PointerExplorer, gdb.TYPE_CODE_PTR : PointerExplorer,
gdb.TYPE_CODE_REF : ReferenceExplorer, gdb.TYPE_CODE_REF : ReferenceExplorer,
gdb.TYPE_CODE_RVALUE_REF : ReferenceExplorer,
gdb.TYPE_CODE_TYPEDEF : TypedefExplorer, gdb.TYPE_CODE_TYPEDEF : TypedefExplorer,
gdb.TYPE_CODE_ARRAY : ArrayExplorer gdb.TYPE_CODE_ARRAY : ArrayExplorer
} }
@ -318,7 +319,6 @@ class ReferenceExplorer(object):
Explorer.explore_type(name, target_type, is_child) Explorer.explore_type(name, target_type, is_child)
return False return False
class ArrayExplorer(object): class ArrayExplorer(object):
"""Internal class used to explore arrays.""" """Internal class used to explore arrays."""

View File

@ -31,8 +31,10 @@ def get_basic_type(type_):
""" """
while (type_.code == gdb.TYPE_CODE_REF or while (type_.code == gdb.TYPE_CODE_REF or
type_.code == gdb.TYPE_CODE_RVALUE_REF or
type_.code == gdb.TYPE_CODE_TYPEDEF): type_.code == gdb.TYPE_CODE_TYPEDEF):
if type_.code == gdb.TYPE_CODE_REF: if (type_.code == gdb.TYPE_CODE_REF or
type_.code == gdb.TYPE_CODE_RVALUE_REF):
type_ = type_.target() type_ = type_.target()
else: else:
type_ = type_.strip_typedefs() type_ = type_.strip_typedefs()

View File

@ -106,6 +106,7 @@ static struct pyty_code pyty_codes[] =
ENTRY (TYPE_CODE_METHODPTR), ENTRY (TYPE_CODE_METHODPTR),
ENTRY (TYPE_CODE_MEMBERPTR), ENTRY (TYPE_CODE_MEMBERPTR),
ENTRY (TYPE_CODE_REF), ENTRY (TYPE_CODE_REF),
ENTRY (TYPE_CODE_RVALUE_REF),
ENTRY (TYPE_CODE_CHAR), ENTRY (TYPE_CODE_CHAR),
ENTRY (TYPE_CODE_BOOL), ENTRY (TYPE_CODE_BOOL),
ENTRY (TYPE_CODE_COMPLEX), ENTRY (TYPE_CODE_COMPLEX),

View File

@ -238,7 +238,7 @@ valpy_referenced_value (PyObject *self, PyObject *args)
/* Return a value which is a reference to the value. */ /* Return a value which is a reference to the value. */
static PyObject * static PyObject *
valpy_reference_value (PyObject *self, PyObject *args) valpy_reference_value (PyObject *self, PyObject *args, enum type_code refcode)
{ {
PyObject *result = NULL; PyObject *result = NULL;
@ -248,7 +248,7 @@ valpy_reference_value (PyObject *self, PyObject *args)
scoped_value_mark free_values; scoped_value_mark free_values;
self_val = ((value_object *) self)->value; self_val = ((value_object *) self)->value;
result = value_to_value_object (value_ref (self_val, TYPE_CODE_REF)); result = value_to_value_object (value_ref (self_val, refcode));
} }
CATCH (except, RETURN_MASK_ALL) CATCH (except, RETURN_MASK_ALL)
{ {
@ -259,6 +259,18 @@ valpy_reference_value (PyObject *self, PyObject *args)
return result; return result;
} }
static PyObject *
valpy_lvalue_reference_value (PyObject *self, PyObject *args)
{
return valpy_reference_value (self, args, TYPE_CODE_REF);
}
static PyObject *
valpy_rvalue_reference_value (PyObject *self, PyObject *args)
{
return valpy_reference_value (self, args, TYPE_CODE_RVALUE_REF);
}
/* Return a "const" qualified version of the value. */ /* Return a "const" qualified version of the value. */
static PyObject * static PyObject *
@ -645,8 +657,7 @@ value_has_field (struct value *v, PyObject *field)
{ {
val_type = value_type (v); val_type = value_type (v);
val_type = check_typedef (val_type); val_type = check_typedef (val_type);
if (TYPE_CODE (val_type) == TYPE_CODE_REF if (TYPE_IS_REFERENCE (val_type) || TYPE_CODE (val_type) == TYPE_CODE_PTR)
|| TYPE_CODE (val_type) == TYPE_CODE_PTR)
val_type = check_typedef (TYPE_TARGET_TYPE (val_type)); val_type = check_typedef (TYPE_TARGET_TYPE (val_type));
type_code = TYPE_CODE (val_type); type_code = TYPE_CODE (val_type);
@ -803,6 +814,9 @@ valpy_getitem (PyObject *self, PyObject *key)
else if (TYPE_CODE (val_type) == TYPE_CODE_REF) else if (TYPE_CODE (val_type) == TYPE_CODE_REF)
res_val = value_cast (lookup_lvalue_reference_type (base_class_type), res_val = value_cast (lookup_lvalue_reference_type (base_class_type),
tmp); tmp);
else if (TYPE_CODE (val_type) == TYPE_CODE_RVALUE_REF)
res_val = value_cast (lookup_rvalue_reference_type (base_class_type),
tmp);
else else
res_val = value_cast (base_class_type, tmp); res_val = value_cast (base_class_type, tmp);
} }
@ -1784,8 +1798,10 @@ reinterpret_cast operator."
{ "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." }, { "dereference", valpy_dereference, METH_NOARGS, "Dereferences the value." },
{ "referenced_value", valpy_referenced_value, METH_NOARGS, { "referenced_value", valpy_referenced_value, METH_NOARGS,
"Return the value referenced by a TYPE_CODE_REF or TYPE_CODE_PTR value." }, "Return the value referenced by a TYPE_CODE_REF or TYPE_CODE_PTR value." },
{ "reference_value", valpy_reference_value, METH_NOARGS, { "reference_value", valpy_lvalue_reference_value, METH_NOARGS,
"Return a value of type TYPE_CODE_REF referencing this value." }, "Return a value of type TYPE_CODE_REF referencing this value." },
{ "rvalue_reference_value", valpy_rvalue_reference_value, METH_NOARGS,
"Return a value of type TYPE_CODE_RVALUE_REF referencing this value." },
{ "const_value", valpy_const_value, METH_NOARGS, { "const_value", valpy_const_value, METH_NOARGS,
"Return a 'const' qualied version of the same value." }, "Return a 'const' qualied version of the same value." },
{ "lazy_string", (PyCFunction) valpy_lazy_string, { "lazy_string", (PyCFunction) valpy_lazy_string,

View File

@ -464,9 +464,10 @@ gdbpy_get_xmethod_result_type (const struct extension_language_defn *extlang,
if (!types_equal (obj_type, this_ptr)) if (!types_equal (obj_type, this_ptr))
obj = value_cast (this_ptr, obj); obj = value_cast (this_ptr, obj);
} }
else if (TYPE_CODE (obj_type) == TYPE_CODE_REF) else if (TYPE_IS_REFERENCE (obj_type))
{ {
struct type *this_ref = lookup_lvalue_reference_type (this_type); struct type *this_ref
= lookup_reference_type (this_type, TYPE_CODE (obj_type));
if (!types_equal (obj_type, this_ref)) if (!types_equal (obj_type, this_ref))
obj = value_cast (this_ref, obj); obj = value_cast (this_ref, obj);