From 326fd672ca2f8c6b38d1068636702766a1f381b5 Mon Sep 17 00:00:00 2001 From: Tom Tromey Date: Wed, 28 Jul 2010 20:50:17 +0000 Subject: [PATCH] gdb 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. --- gdb/ChangeLog | 8 +++ gdb/python/py-type.c | 92 +++++++++++++++++++++------- gdb/testsuite/ChangeLog | 7 +++ gdb/testsuite/gdb.python/py-type.c | 8 +++ gdb/testsuite/gdb.python/py-type.exp | 18 ++++++ 5 files changed, 110 insertions(+), 23 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 6fca089516a..096be2c6801 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,11 @@ +2010-07-28 Tom Tromey + + 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 * 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 b9012554350..529f3019c71 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) { @@ -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) { diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 44ee3b98b01..5739a8e72d4 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,10 @@ +2010-07-28 Tom Tromey + + 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 * 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 f9c15cc4160..46505256d44 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 +struct Temargs +{ +}; + +Temargs temvar; + #endif int diff --git a/gdb/testsuite/gdb.python/py-type.exp b/gdb/testsuite/gdb.python/py-type.exp index 63117ade3aa..1cdb1c1f730 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 -- 2.30.2