gdb
authorTom Tromey <tromey@redhat.com>
Wed, 28 Jul 2010 20:50:17 +0000 (20:50 +0000)
committerTom Tromey <tromey@redhat.com>
Wed, 28 Jul 2010 20:50:17 +0000 (20:50 +0000)
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
gdb/python/py-type.c
gdb/testsuite/ChangeLog
gdb/testsuite/gdb.python/py-type.c
gdb/testsuite/gdb.python/py-type.exp

index 6fca089..096be2c 100644 (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.
index b901255..529f301 100644 (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)
     {
@@ -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;
index 44ee3b9..5739a8e 100644 (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,
index f9c15cc..4650525 100644 (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
index 63117ad..1cdb1c1 100644 (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