aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog8
-rw-r--r--gdb/python/py-type.c92
-rw-r--r--gdb/testsuite/ChangeLog7
-rw-r--r--gdb/testsuite/gdb.python/py-type.c8
-rw-r--r--gdb/testsuite/gdb.python/py-type.exp18
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