/* Python interface to types.
- Copyright (C) 2008-2013 Free Software Foundation, Inc.
+ Copyright (C) 2008-2016 Free Software Foundation, Inc.
This file is part of GDB.
#include "defs.h"
#include "value.h"
-#include "exceptions.h"
#include "python-internal.h"
#include "charset.h"
#include "gdbtypes.h"
struct pyty_type_object *next;
} type_object;
-static PyTypeObject type_object_type
+extern PyTypeObject type_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("type_object");
/* A Field object. */
PyObject *dict;
} field_object;
-static PyTypeObject field_object_type
+extern PyTypeObject field_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("field_object");
/* A type iterator object. */
struct pyty_type_object *source;
} typy_iterator_object;
-static PyTypeObject type_iterator_object_type
+extern PyTypeObject type_iterator_object_type
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("typy_iterator_object");
/* This is used to initialize various gdb.TYPE_ constants. */
\f
+/* Return true if OBJ is of type gdb.Field, false otherwise. */
+
+int
+gdbpy_is_field (PyObject *obj)
+{
+ return PyObject_TypeCheck (obj, &field_object_type);
+}
+
/* Return the code for this type. */
static PyObject *
typy_get_code (PyObject *self, void *closure)
if (!result)
return NULL;
+ arg = type_to_type_object (type);
+ if (arg == NULL)
+ goto fail;
+ if (PyObject_SetAttrString (result, "parent_type", arg) < 0)
+ goto failarg;
+ Py_DECREF (arg);
+
if (!field_is_static (&TYPE_FIELD (type, field)))
{
const char *attrstring;
Py_DECREF (arg);
}
+ arg = NULL;
if (TYPE_FIELD_NAME (type, field))
- arg = PyString_FromString (TYPE_FIELD_NAME (type, field));
- else
+ {
+ const char *field_name = TYPE_FIELD_NAME (type, field);
+
+ if (field_name[0] != '\0')
+ {
+ arg = PyString_FromString (TYPE_FIELD_NAME (type, field));
+ if (arg == NULL)
+ goto fail;
+ }
+ }
+ if (arg == NULL)
{
arg = Py_None;
Py_INCREF (arg);
}
- if (!arg)
- goto fail;
if (PyObject_SetAttrString (result, "name", arg) < 0)
goto failarg;
Py_DECREF (arg);
goto failarg;
Py_DECREF (arg);
- if (TYPE_CODE (type) == TYPE_CODE_CLASS)
+ if (TYPE_CODE (type) == TYPE_CODE_STRUCT)
arg = field < TYPE_N_BASECLASSES (type) ? Py_True : Py_False;
else
arg = Py_False;
gdb_assert_not_reached ("invalid gdbpy_iter_kind");
}
return item;
-
+
fail:
Py_XDECREF (key);
Py_XDECREF (value);
{
PyObject *py_type = self;
PyObject *result = NULL, *iter = NULL;
- volatile struct gdb_exception except;
struct type *type = ((type_object *) py_type)->type;
struct type *checked_type = type;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
+ {
+ checked_type = check_typedef (checked_type);
+ }
+ CATCH (except, RETURN_MASK_ALL)
{
- CHECK_TYPEDEF (checked_type);
+ GDB_PY_HANDLE_EXCEPTION (except);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ END_CATCH
if (checked_type != type)
py_type = type_to_type_object (checked_type);
}
/* Return a sequence of all fields. Each field is a gdb.Field object.
- This method is similar to typy_values, except where the supplied
+ This method is similar to typy_values, except where the supplied
gdb.Type is an array, in which case it returns a list of one entry
which is a gdb.Field object for a range (the array bounds). */
{
struct type *type = ((type_object *) self)->type;
PyObject *r, *rl;
-
+
if (TYPE_CODE (type) != TYPE_CODE_ARRAY)
return typy_fields_items (self, iter_values);
r = convert_field (type, 0);
if (r == NULL)
return NULL;
-
+
rl = Py_BuildValue ("[O]", r);
Py_DECREF (r);
return typy_fields_items (self, iter_keys);
}
-/* Return a sequence of all (name, fields) pairs. Each field is a
+/* Return a sequence of all (name, fields) pairs. Each field is a
gdb.Field object. */
static PyObject *
return typy_fields_items (self, iter_items);
}
+/* Return the type's name, or None. */
+
+static PyObject *
+typy_get_name (PyObject *self, void *closure)
+{
+ struct type *type = ((type_object *) self)->type;
+
+ if (TYPE_NAME (type) == NULL)
+ Py_RETURN_NONE;
+ return PyString_FromString (TYPE_NAME (type));
+}
+
/* Return the type's tag, or None. */
static PyObject *
typy_get_tag (PyObject *self, void *closure)
typy_strip_typedefs (PyObject *self, PyObject *args)
{
struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
type = check_typedef (type);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return type_to_type_object (type);
}
static struct type *
typy_get_composite (struct type *type)
{
- volatile struct gdb_exception except;
for (;;)
{
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
- CHECK_TYPEDEF (type);
+ type = check_typedef (type);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
if (TYPE_CODE (type) != TYPE_CODE_PTR
&& TYPE_CODE (type) != TYPE_CODE_REF)
/* If this is not a struct, union, or enum type, raise TypeError
exception. */
- if (TYPE_CODE (type) != TYPE_CODE_STRUCT
+ if (TYPE_CODE (type) != TYPE_CODE_STRUCT
&& TYPE_CODE (type) != TYPE_CODE_UNION
- && TYPE_CODE (type) != TYPE_CODE_ENUM)
+ && TYPE_CODE (type) != TYPE_CODE_ENUM
+ && TYPE_CODE (type) != TYPE_CODE_FUNC)
{
PyErr_SetString (PyExc_TypeError,
- "Type is not a structure, union, or enum type.");
+ "Type is not a structure, union, enum, or function type.");
return NULL;
}
-
+
return type;
}
PyObject *n2_obj = NULL;
struct type *array = NULL;
struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
if (! PyArg_ParseTuple (args, "l|O", &n1, &n2_obj))
return NULL;
n1 = 0;
}
- if (n2 < n1)
+ if (n2 < n1 - 1) /* Note: An empty array has n2 == n1 - 1. */
{
PyErr_SetString (PyExc_ValueError,
_("Array length must not be negative"));
return NULL;
}
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
array = lookup_array_range_type (type, n1, n2);
if (is_vector)
make_vector_type (array);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return type_to_type_object (array);
}
typy_pointer (PyObject *self, PyObject *args)
{
struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
type = lookup_pointer_type (type);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return type_to_type_object (type);
}
return NULL;
}
return result;
-
+
failarg:
Py_XDECREF (high_bound);
Py_XDECREF (low_bound);
typy_reference (PyObject *self, PyObject *args)
{
struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
type = lookup_reference_type (type);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return type_to_type_object (type);
}
if (!TYPE_TARGET_TYPE (type))
{
- PyErr_SetString (PyExc_RuntimeError,
+ PyErr_SetString (PyExc_RuntimeError,
_("Type does not have a target."));
return NULL;
}
typy_const (PyObject *self, PyObject *args)
{
struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
type = make_cv_type (1, 0, type, NULL);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return type_to_type_object (type);
}
typy_volatile (PyObject *self, PyObject *args)
{
struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
type = make_cv_type (0, 1, type, NULL);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return type_to_type_object (type);
}
typy_unqualified (PyObject *self, PyObject *args)
{
struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
type = make_cv_type (0, 0, type, NULL);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return type_to_type_object (type);
}
typy_get_sizeof (PyObject *self, void *closure)
{
struct type *type = ((type_object *) self)->type;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
check_typedef (type);
}
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ }
+ END_CATCH
+
/* Ignore exceptions. */
return gdb_py_long_from_longest (TYPE_LENGTH (type));
typy_lookup_typename (const char *type_name, const struct block *block)
{
struct type *type = NULL;
- volatile struct gdb_exception except;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
- if (!strncmp (type_name, "struct ", 7))
+ if (startswith (type_name, "struct "))
type = lookup_struct (type_name + 7, NULL);
- else if (!strncmp (type_name, "union ", 6))
+ else if (startswith (type_name, "union "))
type = lookup_union (type_name + 6, NULL);
- else if (!strncmp (type_name, "enum ", 5))
+ else if (startswith (type_name, "enum "))
type = lookup_enum (type_name + 5, NULL);
else
type = lookup_typename (python_language, python_gdbarch,
type_name, block, 0);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return type;
}
struct type *type, *rtype = NULL;
char *type_name = NULL;
enum demangle_component_type demangled_type;
- volatile struct gdb_exception except;
/* Save the type: typy_lookup_type() may (indirectly) overwrite
memory pointed by demangled. */
if (! type)
return NULL;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
/* If the demangled_type matches with one of the types
below, run the corresponding function and save the type
break;
}
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
}
-
+
/* If we have a type from the switch statement above, just return
that. */
if (rtype)
return rtype;
-
+
/* We don't have a type, so lookup the type. */
type_name = cp_comp_to_string (demangled, 10);
type = typy_lookup_typename (type_name, block);
const char *err;
struct type *argtype;
struct cleanup *cleanup;
- volatile struct gdb_exception except;
if (TYPE_NAME (type) == NULL)
{
return NULL;
}
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
/* Note -- this is not thread-safe. */
info = cp_demangled_name_to_comp (TYPE_NAME (type), &err);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
if (! info)
{
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;
}
}
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
type = check_typedef (type);
if (TYPE_CODE (type) == TYPE_CODE_REF)
type = check_typedef (TYPE_TARGET_TYPE (type));
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
/* 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 --
return NULL;
}
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
val = value_of_variable (sym, block);
}
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
return value_to_value_object (val);
}
static PyObject *
typy_str (PyObject *self)
{
- volatile struct gdb_exception except;
- char *thetype = NULL;
- long length = 0;
+ std::string thetype;
PyObject *result;
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
struct cleanup *old_chain;
struct ui_file *stb;
LA_PRINT_TYPE (type_object_to_type (self), "", stb, -1, 0,
&type_print_raw_options);
- thetype = ui_file_xstrdup (stb, &length);
+ thetype = ui_file_as_string (stb);
do_cleanups (old_chain);
}
- if (except.reason < 0)
+ CATCH (except, RETURN_MASK_ALL)
{
- xfree (thetype);
GDB_PY_HANDLE_EXCEPTION (except);
}
+ END_CATCH
- result = PyUnicode_Decode (thetype, length, host_charset (), NULL);
- xfree (thetype);
+ result = PyUnicode_Decode (thetype.c_str (), thetype.length (),
+ host_charset (), NULL);
return result;
}
int result = Py_NE;
struct type *type1 = type_object_to_type (self);
struct type *type2 = type_object_to_type (other);
- volatile struct gdb_exception except;
/* We can only compare ourselves to another Type object, and only
for equality or inequality. */
result = Py_EQ;
else
{
- TRY_CATCH (except, RETURN_MASK_ALL)
+ TRY
{
result = types_deeply_equal (type1, type2);
}
- /* If there is a GDB exception, a comparison is not capable
- (or trusted), so exit. */
- GDB_PY_HANDLE_EXCEPTION (except);
+ CATCH (except, RETURN_MASK_ALL)
+ {
+ /* If there is a GDB exception, a comparison is not capable
+ (or trusted), so exit. */
+ GDB_PY_HANDLE_EXCEPTION (except);
+ }
+ END_CATCH
}
if (op == (result ? Py_EQ : Py_NE))
static void
save_objfile_types (struct objfile *objfile, void *datum)
{
- type_object *obj = datum;
+ type_object *obj = (type_object *) datum;
htab_t copied_types;
struct cleanup *cleanup;
{
struct objfile *objfile = TYPE_OBJFILE (type);
- obj->next = objfile_data (objfile, typy_objfile_data_key);
+ obj->next = ((struct pyty_type_object *)
+ objfile_data (objfile, typy_objfile_data_key));
if (obj->next)
obj->next->prev = obj;
set_objfile_data (objfile, typy_objfile_data_key, obj);
}
/* Implements boolean evaluation of gdb.Type. Handle this like other
- Python objects that don't have a meaningful truth value -- all
+ Python objects that don't have a meaningful truth value -- all
values are true. */
static int
return 1;
}
+/* Return optimized out value of this type. */
+
+static PyObject *
+typy_optimized_out (PyObject *self, PyObject *args)
+{
+ struct type *type = ((type_object *) self)->type;
+
+ return value_to_value_object (allocate_optimized_out_value (type));
+}
+
/* Return a gdb.Field object for the field named by the argument. */
static PyObject *
typy_getitem (PyObject *self, PyObject *key)
{
struct type *type = ((type_object *) self)->type;
- char *field;
int i;
- field = python_string_to_host_string (key);
+ gdb::unique_xmalloc_ptr<char> field = python_string_to_host_string (key);
if (field == NULL)
return NULL;
- /* We want just fields of this type, not of base types, so instead of
+ /* We want just fields of this type, not of base types, so instead of
using lookup_struct_elt_type, portions of that function are
copied here. */
type = typy_get_composite (type);
if (type == NULL)
return NULL;
-
+
for (i = 0; i < TYPE_NFIELDS (type); i++)
{
const char *t_field_name = TYPE_FIELD_NAME (type, i);
- if (t_field_name && (strcmp_iw (t_field_name, field) == 0))
+ if (t_field_name && (strcmp_iw (t_field_name, field.get ()) == 0))
{
return convert_field (type, i);
}
return NULL;
}
-/* Implement the "get" method on the type object. This is the
+/* Implement the "get" method on the type object. This is the
same as getitem if the key is present, but returns the supplied
default value or None if the key is not found. */
typy_get (PyObject *self, PyObject *args)
{
PyObject *key, *defval = Py_None, *result;
-
+
if (!PyArg_UnpackTuple (args, "get", 1, 2, &key, &defval))
return NULL;
-
+
result = typy_getitem (self, key);
if (result != NULL)
return result;
-
+
/* typy_getitem returned error status. If the exception is
KeyError, clear the exception status and return the defval
instead. Otherwise return the exception unchanged. */
if (!PyErr_ExceptionMatches (PyExc_KeyError))
return NULL;
-
+
PyErr_Clear ();
Py_INCREF (defval);
return defval;
if (!PyArg_ParseTuple (args, "s", &field))
return NULL;
- /* We want just fields of this type, not of base types, so instead of
+ /* We want just fields of this type, not of base types, so instead of
using lookup_struct_elt_type, portions of that function are
copied here. */
/* Check that "self" is a structure or union type. */
if (typy_get_composite (((type_object *) self)->type) == NULL)
return NULL;
-
+
typy_iter_obj = PyObject_New (typy_iterator_object,
&type_iterator_object_type);
if (typy_iter_obj == NULL)
typy_iterator_object *iter_obj = (typy_iterator_object *) self;
struct type *type = iter_obj->source->type;
PyObject *result;
-
+
if (iter_obj->field < TYPE_NFIELDS (type))
{
result = make_fielditem (type, iter_obj->field, iter_obj->kind);
{
{ "code", typy_get_code, NULL,
"The code for this type.", NULL },
+ { "name", typy_get_name, NULL,
+ "The name for this type, or None.", NULL },
{ "sizeof", typy_get_sizeof, NULL,
"The size of this type, in bytes.", NULL },
{ "tag", typy_get_tag, NULL,
{ "const", typy_const, METH_NOARGS,
"const () -> Type\n\
Return a const variant of this type." },
+ { "optimized_out", typy_optimized_out, METH_NOARGS,
+ "optimized_out() -> Value\n\
+Return optimized out value of this type." },
{ "fields", typy_fields, METH_NOARGS,
"fields () -> list\n\
Return a list holding all the fields of this type.\n\
NULL /* no "set" method */
};
-static PyTypeObject type_object_type =
+PyTypeObject type_object_type =
{
PyVarObject_HEAD_INIT (NULL, 0)
"gdb.Type", /*tp_name*/
{ NULL }
};
-static PyTypeObject field_object_type =
+PyTypeObject field_object_type =
{
PyVarObject_HEAD_INIT (NULL, 0)
"gdb.Field", /*tp_name*/
0, /* tp_new */
};
-static PyTypeObject type_iterator_object_type = {
+PyTypeObject type_iterator_object_type = {
PyVarObject_HEAD_INIT (NULL, 0)
"gdb.TypeIterator", /*tp_name*/
sizeof (typy_iterator_object), /*tp_basicsize*/