PR python/11060:
	* python/py-type.c (typy_legacy_template_argument): New function,
	extracted from typy_template_argument.
	(typy_template_argument): Use TYPE_TEMPLATE_ARGUMENT.  Return a
	value when needed.
gdb/testsuite
	PR python/11060:
	* gdb.python/py-type.c (Temargs): New template.
	(temvar): New variable.
	* gdb.python/py-type.exp (test_template): New proc.
This commit is contained in:
Tom Tromey 2010-07-28 20:50:17 +00:00
parent 4ac8c4da1d
commit 326fd672ca
5 changed files with 110 additions and 23 deletions

View File

@ -1,3 +1,11 @@
2010-07-28 Tom Tromey <tromey@redhat.com>
PR python/11060:
* python/py-type.c (typy_legacy_template_argument): New function,
extracted from typy_template_argument.
(typy_template_argument): Use TYPE_TEMPLATE_ARGUMENT. Return a
value when needed.
2010-07-28 Oleg Nesterov <oleg@redhat.com>
* remote.c (readchar): Call pop_target in case of SERIAL_ERROR.

View File

@ -509,34 +509,19 @@ typy_lookup_type (struct demangle_component *demangled,
return type;
}
/* This is a helper function for typy_template_argument that is used
when the type does not have template symbols attached. It works by
parsing the type name. This happens with compilers, like older
versions of GCC, that do not emit DW_TAG_template_*. */
static PyObject *
typy_template_argument (PyObject *self, PyObject *args)
typy_legacy_template_argument (struct type *type, struct block *block,
int argno)
{
int i, argno;
struct type *type = ((type_object *) self)->type;
int i;
struct demangle_component *demangled;
const char *err;
struct type *argtype;
struct block *block = NULL;
PyObject *block_obj = NULL;
if (! PyArg_ParseTuple (args, "i|O", &argno, &block_obj))
return NULL;
if (block_obj)
{
block = block_object_to_block (block_obj);
if (! block)
{
PyErr_SetString (PyExc_RuntimeError,
_("Second argument must be block."));
return NULL;
}
}
type = check_typedef (type);
if (TYPE_CODE (type) == TYPE_CODE_REF)
type = check_typedef (TYPE_TARGET_TYPE (type));
if (TYPE_NAME (type) == NULL)
{
@ -583,6 +568,67 @@ typy_template_argument (PyObject *self, PyObject *args)
return type_to_type_object (argtype);
}
static PyObject *
typy_template_argument (PyObject *self, PyObject *args)
{
int argno;
struct type *type = ((type_object *) self)->type;
struct block *block = NULL;
PyObject *block_obj = NULL;
struct symbol *sym;
struct value *val = NULL;
volatile struct gdb_exception except;
if (! PyArg_ParseTuple (args, "i|O", &argno, &block_obj))
return NULL;
if (block_obj)
{
block = block_object_to_block (block_obj);
if (! block)
{
PyErr_SetString (PyExc_RuntimeError,
_("Second argument must be block."));
return NULL;
}
}
type = check_typedef (type);
if (TYPE_CODE (type) == TYPE_CODE_REF)
type = check_typedef (TYPE_TARGET_TYPE (type));
/* We might not have DW_TAG_template_*, so try to parse the type's
name. This is inefficient if we do not have a template type --
but that is going to wind up as an error anyhow. */
if (! TYPE_N_TEMPLATE_ARGUMENTS (type))
return typy_legacy_template_argument (type, block, argno);
if (argno >= TYPE_N_TEMPLATE_ARGUMENTS (type))
{
PyErr_Format (PyExc_RuntimeError, _("No argument %d in template."),
argno);
return NULL;
}
sym = TYPE_TEMPLATE_ARGUMENT (type, argno);
if (SYMBOL_CLASS (sym) == LOC_TYPEDEF)
return type_to_type_object (SYMBOL_TYPE (sym));
else if (SYMBOL_CLASS (sym) == LOC_OPTIMIZED_OUT)
{
PyErr_Format (PyExc_RuntimeError,
_("Template argument is optimized out"));
return NULL;
}
TRY_CATCH (except, RETURN_MASK_ALL)
{
val = value_of_variable (sym, block);
}
GDB_PY_HANDLE_EXCEPTION (except);
return value_to_value_object (val);
}
static PyObject *
typy_str (PyObject *self)
{

View File

@ -1,3 +1,10 @@
2010-07-28 Tom Tromey <tromey@redhat.com>
PR python/11060:
* gdb.python/py-type.c (Temargs): New template.
(temvar): New variable.
* gdb.python/py-type.exp (test_template): New proc.
2010-07-28 Daniel Jacobowitz <dan@codesourcery.com>
* gdb.cp/member-ptr.exp, gdb.cp/printmethod.exp,

View File

@ -33,6 +33,14 @@ struct D : C
int e;
int f;
};
template<typename T, int I, int C::*MP>
struct Temargs
{
};
Temargs<D, 23, &C::c> temvar;
#endif
int

View File

@ -126,6 +126,23 @@ proc test_range {} {
gdb_test "python print st.type.range()" "RuntimeError: This type does not have a range.*" "Check range for non ranged type."
}
# Some tests of template arguments.
proc test_template {} {
gdb_py_test_silent_cmd \
"python ttype = gdb.parse_and_eval('temvar').type" \
"get type of temvar" \
1
gdb_test "python print ttype.template_argument(0)" "D"
gdb_test "python print isinstance(ttype.template_argument(0), gdb.Type)" \
"True"
# The next two tests require a GCC that emits DW_TAG_template_*.
gdb_test "python print ttype.template_argument(1)" "23"
gdb_test "python print isinstance(ttype.template_argument(1), gdb.Value)" \
"True"
setup_kfail "gcc/41736" *-*-*
gdb_test "python print ttype.template_argument(2)" "&C::c"
}
# Perform C Tests.
build_inferior "c"
@ -144,3 +161,4 @@ runto_bp "break to inspect struct and array."
test_fields "c++"
test_base_class
test_range
test_template