Add block['var'] accessor
[deliverable/binutils-gdb.git] / gdb / python / py-block.c
index f0b8322270617845835c9159d9d7af4ee19cf6d2..4dc47ff169de9af3eea16eb30bc152b1a742175a 100644 (file)
@@ -1,6 +1,6 @@
 /* Python interface to blocks.
 
-   Copyright (C) 2008-2013 Free Software Foundation, Inc.
+   Copyright (C) 2008-2019 Free Software Foundation, Inc.
 
    This file is part of GDB.
 
@@ -23,7 +23,6 @@
 #include "symtab.h"
 #include "python-internal.h"
 #include "objfiles.h"
-#include "symtab.h"
 
 typedef struct blpy_block_object {
   PyObject_HEAD
@@ -78,7 +77,8 @@ typedef struct {
       }                                                                        \
   } while (0)
 
-static PyTypeObject block_syms_iterator_object_type;
+extern PyTypeObject block_syms_iterator_object_type
+    CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("block_syms_iterator_object");
 static const struct objfile_data *blpy_objfile_data_key;
 
 static PyObject *
@@ -109,7 +109,7 @@ blpy_get_start (PyObject *self, void *closure)
 
   BLPY_REQUIRE_VALID (self, block);
 
-  return gdb_py_object_from_ulongest (BLOCK_START (block));
+  return gdb_py_object_from_ulongest (BLOCK_START (block)).release ();
 }
 
 static PyObject *
@@ -119,7 +119,7 @@ blpy_get_end (PyObject *self, void *closure)
 
   BLPY_REQUIRE_VALID (self, block);
 
-  return gdb_py_object_from_ulongest (BLOCK_END (block));
+  return gdb_py_object_from_ulongest (BLOCK_END (block)).release ();
 }
 
 static PyObject *
@@ -224,6 +224,43 @@ blpy_is_static (PyObject *self, void *closure)
   Py_RETURN_FALSE;
 }
 
+/* Given a string, returns the gdb.Symbol representing that symbol in this
+   block.  If such a symbol does not exist, returns NULL with a Python
+   exception.  */
+
+static PyObject *
+blpy_getitem (PyObject *self, PyObject *key)
+{
+  const struct block *block;
+
+  BLPY_REQUIRE_VALID (self, block);
+
+  gdb::unique_xmalloc_ptr<char> name = python_string_to_host_string (key);
+  if (name == nullptr)
+    return nullptr;
+
+  lookup_name_info lookup_name (name.get(), symbol_name_match_type::FULL);
+
+  /* We use ALL_BLOCK_SYMBOLS_WITH_NAME instead of block_lookup_symbol so
+     that we can look up symbols irrespective of the domain, matching the
+     iterator. It would be confusing if the iterator returns symbols you
+     can't find via getitem.  */
+  struct block_iterator iter;
+  struct symbol *sym = nullptr;
+  ALL_BLOCK_SYMBOLS_WITH_NAME (block, lookup_name, iter, sym)
+    {
+      /* Just stop at the first match */
+      break;
+    }
+
+  if (sym == nullptr)
+    {
+      PyErr_SetObject (PyExc_KeyError, key);
+      return nullptr;
+    }
+  return symbol_to_symbol_object (sym);
+}
+
 static void
 blpy_dealloc (PyObject *obj)
 {
@@ -255,7 +292,8 @@ set_block (block_object *obj, const struct block *block,
   if (objfile)
     {
       obj->objfile = objfile;
-      obj->next = objfile_data (objfile, blpy_objfile_data_key);
+      obj->next = ((struct blpy_block_object *)
+                  objfile_data (objfile, blpy_objfile_data_key));
       if (obj->next)
        obj->next->prev = obj;
       set_objfile_data (objfile, blpy_objfile_data_key, obj);
@@ -364,43 +402,6 @@ blpy_iter_is_valid (PyObject *self, PyObject *args)
   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)
-{
-  gdb_py_ulongest pc;
-  struct block *block = NULL;
-  struct obj_section *section = NULL;
-  struct symtab *symtab = NULL;
-  volatile struct gdb_exception except;
-
-  if (!PyArg_ParseTuple (args, GDB_PY_LLU_ARG, &pc))
-    return NULL;
-
-  TRY_CATCH (except, RETURN_MASK_ALL)
-    {
-      section = find_pc_mapped_section (pc);
-      symtab = find_pc_sect_symtab (pc, section);
-
-      if (symtab != NULL && symtab->objfile != NULL)
-       block = block_for_pc (pc);
-    }
-  GDB_PY_HANDLE_EXCEPTION (except);
-
-  if (!symtab || symtab->objfile == NULL)
-    {
-      PyErr_SetString (PyExc_RuntimeError,
-                      _("Cannot locate object file for block."));
-      return NULL;
-    }
-
-  if (block)
-    return block_to_block_object (block, symtab->objfile);
-
-  Py_RETURN_NONE;
-}
-
 /* This function is called when an objfile is about to be freed.
    Invalidate the block as further actions on the block would result
    in bad data.  All access to obj->symbol should be gated by
@@ -409,7 +410,7 @@ gdbpy_block_for_pc (PyObject *self, PyObject *args)
 static void
 del_objfile_blocks (struct objfile *objfile, void *datum)
 {
-  block_object *obj = datum;
+  block_object *obj = (block_object *) datum;
 
   while (obj)
     {
@@ -424,16 +425,16 @@ del_objfile_blocks (struct objfile *objfile, void *datum)
     }
 }
 
-void
+int
 gdbpy_initialize_blocks (void)
 {
   block_object_type.tp_new = PyType_GenericNew;
   if (PyType_Ready (&block_object_type) < 0)
-    return;
+    return -1;
 
   block_syms_iterator_object_type.tp_new = PyType_GenericNew;
   if (PyType_Ready (&block_syms_iterator_object_type) < 0)
-    return;
+    return -1;
 
   /* Register an objfile "free" callback so we can properly
      invalidate blocks when an object file is about to be
@@ -441,12 +442,12 @@ gdbpy_initialize_blocks (void)
   blpy_objfile_data_key
     = register_objfile_data_with_cleanup (NULL, del_objfile_blocks);
 
-  Py_INCREF (&block_object_type);
-  PyModule_AddObject (gdb_module, "Block", (PyObject *) &block_object_type);
+  if (gdb_pymodule_addobject (gdb_module, "Block",
+                             (PyObject *) &block_object_type) < 0)
+    return -1;
 
-  Py_INCREF (&block_syms_iterator_object_type);
-  PyModule_AddObject (gdb_module, "BlockIterator",
-                     (PyObject *) &block_syms_iterator_object_type);
+  return gdb_pymodule_addobject (gdb_module, "BlockIterator",
+                                (PyObject *) &block_syms_iterator_object_type);
 }
 
 \f
@@ -458,7 +459,7 @@ Return true if this block is valid, false if not." },
   {NULL}  /* Sentinel */
 };
 
-static PyGetSetDef block_object_getset[] = {
+static gdb_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 },
   { "function", blpy_get_function, NULL,
@@ -476,6 +477,12 @@ static PyGetSetDef block_object_getset[] = {
   { NULL }  /* Sentinel */
 };
 
+static PyMappingMethods block_object_as_mapping = {
+  NULL,
+  blpy_getitem,
+  NULL
+};
+
 PyTypeObject block_object_type = {
   PyVarObject_HEAD_INIT (NULL, 0)
   "gdb.Block",                   /*tp_name*/
@@ -489,7 +496,7 @@ PyTypeObject block_object_type = {
   0,                             /*tp_repr*/
   0,                             /*tp_as_number*/
   0,                             /*tp_as_sequence*/
-  0,                             /*tp_as_mapping*/
+  &block_object_as_mapping,      /*tp_as_mapping*/
   0,                             /*tp_hash */
   0,                             /*tp_call*/
   0,                             /*tp_str*/
@@ -516,7 +523,7 @@ Return true if this block iterator is valid, false if not." },
   {NULL}  /* Sentinel */
 };
 
-static PyTypeObject block_syms_iterator_object_type = {
+PyTypeObject block_syms_iterator_object_type = {
   PyVarObject_HEAD_INIT (NULL, 0)
   "gdb.BlockIterator",           /*tp_name*/
   sizeof (block_syms_iterator_object),       /*tp_basicsize*/
This page took 0.029681 seconds and 4 git commands to generate.