* tracepoint.c (scope_info): Update.
[deliverable/binutils-gdb.git] / gdb / python / py-block.c
index d0170306d009b829d7331d7933f2b704382eba57..68d0a1595cb87a419f14ae88aa2a357b3e1c7819 100644 (file)
@@ -1,6 +1,6 @@
 /* Python interface to blocks.
 
-   Copyright (C) 2008, 2009, 2010 Free Software Foundation, Inc.
+   Copyright (C) 2008-2012 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -28,7 +28,7 @@
 typedef struct blpy_block_object {
   PyObject_HEAD
   /* The GDB block structure that represents a frame's code block.  */
-  struct block *block;
+  const struct block *block;
   /* The backing object file.  There is no direct relationship in GDB
      between a block and an object file.  When a block is created also
      store a pointer to the object file for later use.  */
@@ -41,10 +41,10 @@ typedef struct blpy_block_object {
 
 typedef struct {
   PyObject_HEAD
-  /* The block dictionary of symbols.  */
-  struct dictionary *dict;
-  /* The iterator for that dictionary.  */
-  struct dict_iterator iter;
+  /* The block.  */
+  const struct block *block;
+  /* The iterator for that block.  */
+  struct block_iterator iter;
   /* Has the iterator been initialized flag.  */
   int initialized_p;
   /* Pointer back to the original source block object.  Needed to
@@ -85,7 +85,7 @@ static PyObject *
 blpy_iter (PyObject *self)
 {
   block_syms_iterator_object *block_iter_obj;
-  struct block *block = NULL;
+  const struct block *block = NULL;
 
   BLPY_REQUIRE_VALID (self, block);
 
@@ -94,7 +94,7 @@ blpy_iter (PyObject *self)
   if (block_iter_obj == NULL)
       return NULL;
 
-  block_iter_obj->dict = BLOCK_DICT (block);
+  block_iter_obj->block = block;
   block_iter_obj->initialized_p = 0;
   Py_INCREF (self);
   block_iter_obj->source = (block_object *) self;
@@ -105,28 +105,28 @@ blpy_iter (PyObject *self)
 static PyObject *
 blpy_get_start (PyObject *self, void *closure)
 {
-  struct block *block = NULL;
+  const struct block *block = NULL;
 
   BLPY_REQUIRE_VALID (self, block);
 
-  return PyLong_FromUnsignedLongLong (BLOCK_START (block));
+  return gdb_py_object_from_ulongest (BLOCK_START (block));
 }
 
 static PyObject *
 blpy_get_end (PyObject *self, void *closure)
 {
-  struct block *block = NULL;
+  const struct block *block = NULL;
 
   BLPY_REQUIRE_VALID (self, block);
 
-  return PyLong_FromUnsignedLongLong (BLOCK_END (block));
+  return gdb_py_object_from_ulongest (BLOCK_END (block));
 }
 
 static PyObject *
 blpy_get_function (PyObject *self, void *closure)
 {
   struct symbol *sym;
-  struct block *block = NULL;
+  const struct block *block;
 
   BLPY_REQUIRE_VALID (self, block);
 
@@ -140,8 +140,8 @@ blpy_get_function (PyObject *self, void *closure)
 static PyObject *
 blpy_get_superblock (PyObject *self, void *closure)
 {
-  struct block *block = NULL;
-  struct block *super_block = NULL;
+  const struct block *block;
+  const struct block *super_block;
   block_object *self_obj  = (block_object *) self;
 
   BLPY_REQUIRE_VALID (self, block);
@@ -153,6 +153,77 @@ blpy_get_superblock (PyObject *self, void *closure)
   Py_RETURN_NONE;
 }
 
+/* Return the global block associated to this block.  */
+
+static PyObject *
+blpy_get_global_block (PyObject *self, void *closure)
+{
+  const struct block *block;
+  const struct block *global_block;
+  block_object *self_obj  = (block_object *) self;
+
+  BLPY_REQUIRE_VALID (self, block);
+
+  global_block = block_global_block (block);
+
+  return block_to_block_object (global_block,
+                               self_obj->objfile);
+
+}
+
+/* Return the static block associated to this block.  Return None
+   if we cannot get the static block (this is the global block).  */
+
+static PyObject *
+blpy_get_static_block (PyObject *self, void *closure)
+{
+  const struct block *block;
+  const struct block *static_block;
+  block_object *self_obj  = (block_object *) self;
+
+  BLPY_REQUIRE_VALID (self, block);
+
+  if (BLOCK_SUPERBLOCK (block) == NULL)
+    Py_RETURN_NONE;
+
+  static_block = block_static_block (block);
+
+  return block_to_block_object (static_block, self_obj->objfile);
+}
+
+/* Implementation of gdb.Block.is_global (self) -> Boolean.
+   Returns True if this block object is a global block.  */
+
+static PyObject *
+blpy_is_global (PyObject *self, void *closure)
+{
+  const struct block *block;
+
+  BLPY_REQUIRE_VALID (self, block);
+
+  if (BLOCK_SUPERBLOCK (block))
+    Py_RETURN_FALSE;
+
+  Py_RETURN_TRUE;
+}
+
+/* Implementation of gdb.Block.is_static (self) -> Boolean.
+   Returns True if this block object is a static block.  */
+
+static PyObject *
+blpy_is_static (PyObject *self, void *closure)
+{
+  const struct block *block;
+
+  BLPY_REQUIRE_VALID (self, block);
+
+  if (BLOCK_SUPERBLOCK (block) != NULL
+     && BLOCK_SUPERBLOCK (BLOCK_SUPERBLOCK (block)) == NULL)
+    Py_RETURN_TRUE;
+
+  Py_RETURN_FALSE;
+}
+
 static void
 blpy_dealloc (PyObject *obj)
 {
@@ -173,10 +244,10 @@ blpy_dealloc (PyObject *obj)
 /* Given a block, and a block_object that has previously been
    allocated and initialized, populate the block_object with the
    struct block data.  Also, register the block_object life-cycle
-   with the life-cycle of the the object file associated with this
+   with the life-cycle of the object file associated with this
    block, if needed.  */
 static void
-set_block (block_object *obj, struct block *block,
+set_block (block_object *obj, const struct block *block,
           struct objfile *objfile)
 {
   obj->block = block;
@@ -196,7 +267,7 @@ set_block (block_object *obj, struct block *block,
 /* Create a new block object (gdb.Block) that encapsulates the struct
    block object from GDB.  */
 PyObject *
-block_to_block_object (struct block *block, struct objfile *objfile)
+block_to_block_object (const struct block *block, struct objfile *objfile)
 {
   block_object *block_obj;
 
@@ -208,7 +279,7 @@ block_to_block_object (struct block *block, struct objfile *objfile)
 }
 
 /* Return struct block reference that is wrapped by this object.  */
-struct block *
+const struct block *
 block_object_to_block (PyObject *obj)
 {
   if (! PyObject_TypeCheck (obj, &block_object_type))
@@ -240,11 +311,11 @@ blpy_block_syms_iternext (PyObject *self)
 
   if (!iter_obj->initialized_p)
     {
-      sym = dict_iterator_first (iter_obj->dict,  &(iter_obj->iter));
+      sym = block_iterator_first (iter_obj->block,  &(iter_obj->iter));
       iter_obj->initialized_p = 1;
     }
   else
-    sym = dict_iterator_next (&(iter_obj->iter));
+    sym = block_iterator_next (&(iter_obj->iter));
 
   if (sym == NULL)
     {
@@ -259,25 +330,61 @@ static void
 blpy_block_syms_dealloc (PyObject *obj)
 {
   block_syms_iterator_object *iter_obj = (block_syms_iterator_object *) obj;
+
   Py_XDECREF (iter_obj->source);
 }
 
+/* Implementation of gdb.Block.is_valid (self) -> Boolean.
+   Returns True if this block object still exists in GDB.  */
+
+static PyObject *
+blpy_is_valid (PyObject *self, PyObject *args)
+{
+  const struct block *block;
+
+  block = block_object_to_block (self);
+  if (block == NULL)
+    Py_RETURN_FALSE;
+
+  Py_RETURN_TRUE;
+}
+
+/* Implementation of gdb.BlockIterator.is_valid (self) -> Boolean.
+   Returns True if this block iterator object still exists in GDB  */
+
+static PyObject *
+blpy_iter_is_valid (PyObject *self, PyObject *args)
+{
+  block_syms_iterator_object *iter_obj =
+    (block_syms_iterator_object *) self;
+
+  if (iter_obj->source->block == NULL)
+    Py_RETURN_FALSE;
+
+  Py_RETURN_TRUE;
+}
+
 /* Return the innermost lexical block containing the specified pc value,
    or 0 if there is none.  */
 PyObject *
 gdbpy_block_for_pc (PyObject *self, PyObject *args)
 {
-  unsigned PY_LONG_LONG pc;
+  gdb_py_ulongest pc;
   struct block *block;
-  struct obj_section *section;
-  struct symtab *symtab;
-  PyObject *sym_obj;
+  struct obj_section *section = NULL;
+  struct symtab *symtab = NULL;
+  volatile struct gdb_exception except;
 
-  if (!PyArg_ParseTuple (args, "K", &pc))
+  if (!PyArg_ParseTuple (args, GDB_PY_LLU_ARG, &pc))
     return NULL;
 
-  section = find_pc_mapped_section (pc);
-  symtab = find_pc_sect_symtab (pc, section);
+  TRY_CATCH (except, RETURN_MASK_ALL)
+    {
+      section = find_pc_mapped_section (pc);
+      symtab = find_pc_sect_symtab (pc, section);
+    }
+  GDB_PY_HANDLE_EXCEPTION (except);
+
   if (!symtab || symtab->objfile == NULL)
     {
       PyErr_SetString (PyExc_RuntimeError,
@@ -301,6 +408,7 @@ static void
 del_objfile_blocks (struct objfile *objfile, void *datum)
 {
   block_object *obj = datum;
+
   while (obj)
     {
       block_object *next = obj->next;
@@ -341,6 +449,13 @@ gdbpy_initialize_blocks (void)
 
 \f
 
+static PyMethodDef block_object_methods[] = {
+  { "is_valid", blpy_is_valid, METH_NOARGS,
+    "is_valid () -> Boolean.\n\
+Return true if this block is valid, false if not." },
+  {NULL}  /* Sentinel */
+};
+
 static PyGetSetDef block_object_getset[] = {
   { "start", blpy_get_start, NULL, "Start address of the block.", NULL },
   { "end", blpy_get_end, NULL, "End address of the block.", NULL },
@@ -348,6 +463,14 @@ static PyGetSetDef block_object_getset[] = {
     "Symbol that names the block, or None.", NULL },
   { "superblock", blpy_get_superblock, NULL,
     "Block containing the block, or None.", NULL },
+  { "global_block", blpy_get_global_block, NULL,
+    "Block containing the global block.", NULL },
+  { "static_block", blpy_get_static_block, NULL,
+    "Block containing the static block.", NULL },
+  { "is_static", blpy_is_static, NULL,
+    "Whether this block is a static block.", NULL },
+  { "is_global", blpy_is_global, NULL,
+    "Whether this block is a global block.", NULL },
   { NULL }  /* Sentinel */
 };
 
@@ -380,11 +503,18 @@ PyTypeObject block_object_type = {
   0,                             /* tp_weaklistoffset */
   blpy_iter,                     /* tp_iter */
   0,                             /* tp_iternext */
-  0,                             /* tp_methods */
+  block_object_methods,                  /* tp_methods */
   0,                             /* tp_members */
   block_object_getset            /* tp_getset */
 };
 
+static PyMethodDef block_iterator_object_methods[] = {
+  { "is_valid", blpy_iter_is_valid, METH_NOARGS,
+    "is_valid () -> Boolean.\n\
+Return true if this block iterator is valid, false if not." },
+  {NULL}  /* Sentinel */
+};
+
 static PyTypeObject block_syms_iterator_object_type = {
   PyObject_HEAD_INIT (NULL)
   0,                             /*ob_size*/
@@ -414,5 +544,5 @@ static PyTypeObject block_syms_iterator_object_type = {
   0,                             /*tp_weaklistoffset */
   blpy_block_syms_iter,           /*tp_iter */
   blpy_block_syms_iternext,      /*tp_iternext */
-  0                              /*tp_methods */
+  block_iterator_object_methods   /*tp_methods */
 };
This page took 0.029286 seconds and 4 git commands to generate.