diff options
-rw-r--r-- | gdb/ChangeLog | 8 | ||||
-rw-r--r-- | gdb/python/py-type.c | 92 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/py-type.c | 8 | ||||
-rw-r--r-- | gdb/testsuite/gdb.python/py-type.exp | 18 |
5 files changed, 110 insertions, 23 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6fca089..096be2c 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -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. diff --git a/gdb/python/py-type.c b/gdb/python/py-type.c index b901255..529f301 100644 --- a/gdb/python/py-type.c +++ b/gdb/python/py-type.c @@ -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) { @@ -584,6 +569,67 @@ typy_template_argument (PyObject *self, PyObject *args) } 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) { volatile struct gdb_exception except; diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 44ee3b9..5739a8e 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -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, diff --git a/gdb/testsuite/gdb.python/py-type.c b/gdb/testsuite/gdb.python/py-type.c index f9c15cc..4650525 100644 --- a/gdb/testsuite/gdb.python/py-type.c +++ b/gdb/testsuite/gdb.python/py-type.c @@ -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 diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp index 63117ad..1cdb1c1 100644 --- a/gdb/testsuite/gdb.python/py-type.exp +++ b/gdb/testsuite/gdb.python/py-type.exp @@ -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 |