123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775 |
- /* Python interface to symbols.
- Copyright (C) 2008-2022 Free Software Foundation, Inc.
- This file is part of GDB.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
- #include "defs.h"
- #include "block.h"
- #include "frame.h"
- #include "symtab.h"
- #include "python-internal.h"
- #include "objfiles.h"
- #include "symfile.h"
- struct symbol_object {
- PyObject_HEAD
- /* The GDB symbol structure this object is wrapping. */
- struct symbol *symbol;
- /* A symbol object is associated with an objfile, so keep track with
- doubly-linked list, rooted in the objfile. This lets us
- invalidate the underlying struct symbol when the objfile is
- deleted. */
- symbol_object *prev;
- symbol_object *next;
- };
- /* Require a valid symbol. All access to symbol_object->symbol should be
- gated by this call. */
- #define SYMPY_REQUIRE_VALID(symbol_obj, symbol) \
- do { \
- symbol = symbol_object_to_symbol (symbol_obj); \
- if (symbol == NULL) \
- { \
- PyErr_SetString (PyExc_RuntimeError, \
- _("Symbol is invalid.")); \
- return NULL; \
- } \
- } while (0)
- static const struct objfile_data *sympy_objfile_data_key;
- static PyObject *
- sympy_str (PyObject *self)
- {
- PyObject *result;
- struct symbol *symbol = NULL;
- SYMPY_REQUIRE_VALID (self, symbol);
- result = PyUnicode_FromString (symbol->print_name ());
- return result;
- }
- static PyObject *
- sympy_get_type (PyObject *self, void *closure)
- {
- struct symbol *symbol = NULL;
- SYMPY_REQUIRE_VALID (self, symbol);
- if (symbol->type () == NULL)
- {
- Py_INCREF (Py_None);
- return Py_None;
- }
- return type_to_type_object (symbol->type ());
- }
- static PyObject *
- sympy_get_symtab (PyObject *self, void *closure)
- {
- struct symbol *symbol = NULL;
- SYMPY_REQUIRE_VALID (self, symbol);
- if (!symbol->is_objfile_owned ())
- Py_RETURN_NONE;
- return symtab_to_symtab_object (symbol_symtab (symbol));
- }
- static PyObject *
- sympy_get_name (PyObject *self, void *closure)
- {
- struct symbol *symbol = NULL;
- SYMPY_REQUIRE_VALID (self, symbol);
- return PyUnicode_FromString (symbol->natural_name ());
- }
- static PyObject *
- sympy_get_linkage_name (PyObject *self, void *closure)
- {
- struct symbol *symbol = NULL;
- SYMPY_REQUIRE_VALID (self, symbol);
- return PyUnicode_FromString (symbol->linkage_name ());
- }
- static PyObject *
- sympy_get_print_name (PyObject *self, void *closure)
- {
- struct symbol *symbol = NULL;
- SYMPY_REQUIRE_VALID (self, symbol);
- return sympy_str (self);
- }
- static PyObject *
- sympy_get_addr_class (PyObject *self, void *closure)
- {
- struct symbol *symbol = NULL;
- SYMPY_REQUIRE_VALID (self, symbol);
- return gdb_py_object_from_longest (symbol->aclass ()).release ();
- }
- static PyObject *
- sympy_is_argument (PyObject *self, void *closure)
- {
- struct symbol *symbol = NULL;
- SYMPY_REQUIRE_VALID (self, symbol);
- return PyBool_FromLong (symbol->is_argument ());
- }
- static PyObject *
- sympy_is_constant (PyObject *self, void *closure)
- {
- struct symbol *symbol = NULL;
- enum address_class theclass;
- SYMPY_REQUIRE_VALID (self, symbol);
- theclass = symbol->aclass ();
- return PyBool_FromLong (theclass == LOC_CONST || theclass == LOC_CONST_BYTES);
- }
- static PyObject *
- sympy_is_function (PyObject *self, void *closure)
- {
- struct symbol *symbol = NULL;
- enum address_class theclass;
- SYMPY_REQUIRE_VALID (self, symbol);
- theclass = symbol->aclass ();
- return PyBool_FromLong (theclass == LOC_BLOCK);
- }
- static PyObject *
- sympy_is_variable (PyObject *self, void *closure)
- {
- struct symbol *symbol = NULL;
- enum address_class theclass;
- SYMPY_REQUIRE_VALID (self, symbol);
- theclass = symbol->aclass ();
- return PyBool_FromLong (!symbol->is_argument ()
- && (theclass == LOC_LOCAL || theclass == LOC_REGISTER
- || theclass == LOC_STATIC || theclass == LOC_COMPUTED
- || theclass == LOC_OPTIMIZED_OUT));
- }
- /* Implementation of gdb.Symbol.needs_frame -> Boolean.
- Returns true iff the symbol needs a frame for evaluation. */
- static PyObject *
- sympy_needs_frame (PyObject *self, void *closure)
- {
- struct symbol *symbol = NULL;
- int result = 0;
- SYMPY_REQUIRE_VALID (self, symbol);
- try
- {
- result = symbol_read_needs_frame (symbol);
- }
- catch (const gdb_exception &except)
- {
- GDB_PY_HANDLE_EXCEPTION (except);
- }
- if (result)
- Py_RETURN_TRUE;
- Py_RETURN_FALSE;
- }
- /* Implementation of gdb.Symbol.line -> int.
- Returns the line number at which the symbol was defined. */
- static PyObject *
- sympy_line (PyObject *self, void *closure)
- {
- struct symbol *symbol = NULL;
- SYMPY_REQUIRE_VALID (self, symbol);
- return gdb_py_object_from_longest (symbol->line ()).release ();
- }
- /* Implementation of gdb.Symbol.is_valid (self) -> Boolean.
- Returns True if this Symbol still exists in GDB. */
- static PyObject *
- sympy_is_valid (PyObject *self, PyObject *args)
- {
- struct symbol *symbol = NULL;
- symbol = symbol_object_to_symbol (self);
- if (symbol == NULL)
- Py_RETURN_FALSE;
- Py_RETURN_TRUE;
- }
- /* Implementation of gdb.Symbol.value (self[, frame]) -> gdb.Value. Returns
- the value of the symbol, or an error in various circumstances. */
- static PyObject *
- sympy_value (PyObject *self, PyObject *args)
- {
- struct symbol *symbol = NULL;
- struct frame_info *frame_info = NULL;
- PyObject *frame_obj = NULL;
- struct value *value = NULL;
- if (!PyArg_ParseTuple (args, "|O", &frame_obj))
- return NULL;
- if (frame_obj != NULL && !PyObject_TypeCheck (frame_obj, &frame_object_type))
- {
- PyErr_SetString (PyExc_TypeError, "argument is not a frame");
- return NULL;
- }
- SYMPY_REQUIRE_VALID (self, symbol);
- if (symbol->aclass () == LOC_TYPEDEF)
- {
- PyErr_SetString (PyExc_TypeError, "cannot get the value of a typedef");
- return NULL;
- }
- try
- {
- if (frame_obj != NULL)
- {
- frame_info = frame_object_to_frame_info (frame_obj);
- if (frame_info == NULL)
- error (_("invalid frame"));
- }
- if (symbol_read_needs_frame (symbol) && frame_info == NULL)
- error (_("symbol requires a frame to compute its value"));
- /* TODO: currently, we have no way to recover the block in which SYMBOL
- was found, so we have no block to pass to read_var_value. This will
- yield an incorrect value when symbol is not local to FRAME_INFO (this
- can happen with nested functions). */
- value = read_var_value (symbol, NULL, frame_info);
- }
- catch (const gdb_exception &except)
- {
- GDB_PY_HANDLE_EXCEPTION (except);
- }
- return value_to_value_object (value);
- }
- /* Given a symbol, and a symbol_object that has previously been
- allocated and initialized, populate the symbol_object with the
- struct symbol data. Also, register the symbol_object life-cycle
- with the life-cycle of the object file associated with this
- symbol, if needed. */
- static void
- set_symbol (symbol_object *obj, struct symbol *symbol)
- {
- obj->symbol = symbol;
- obj->prev = NULL;
- if (symbol->is_objfile_owned ()
- && symbol_symtab (symbol) != NULL)
- {
- struct objfile *objfile = symbol_objfile (symbol);
- obj->next = ((symbol_object *)
- objfile_data (objfile, sympy_objfile_data_key));
- if (obj->next)
- obj->next->prev = obj;
- set_objfile_data (objfile, sympy_objfile_data_key, obj);
- }
- else
- obj->next = NULL;
- }
- /* Create a new symbol object (gdb.Symbol) that encapsulates the struct
- symbol object from GDB. */
- PyObject *
- symbol_to_symbol_object (struct symbol *sym)
- {
- symbol_object *sym_obj;
- sym_obj = PyObject_New (symbol_object, &symbol_object_type);
- if (sym_obj)
- set_symbol (sym_obj, sym);
- return (PyObject *) sym_obj;
- }
- /* Return the symbol that is wrapped by this symbol object. */
- struct symbol *
- symbol_object_to_symbol (PyObject *obj)
- {
- if (! PyObject_TypeCheck (obj, &symbol_object_type))
- return NULL;
- return ((symbol_object *) obj)->symbol;
- }
- static void
- sympy_dealloc (PyObject *obj)
- {
- symbol_object *sym_obj = (symbol_object *) obj;
- if (sym_obj->prev)
- sym_obj->prev->next = sym_obj->next;
- else if (sym_obj->symbol != NULL
- && sym_obj->symbol->is_objfile_owned ()
- && symbol_symtab (sym_obj->symbol) != NULL)
- {
- set_objfile_data (symbol_objfile (sym_obj->symbol),
- sympy_objfile_data_key, sym_obj->next);
- }
- if (sym_obj->next)
- sym_obj->next->prev = sym_obj->prev;
- sym_obj->symbol = NULL;
- Py_TYPE (obj)->tp_free (obj);
- }
- /* Implementation of
- gdb.lookup_symbol (name [, block] [, domain]) -> (symbol, is_field_of_this)
- A tuple with 2 elements is always returned. The first is the symbol
- object or None, the second is a boolean with the value of
- is_a_field_of_this (see comment in lookup_symbol_in_language). */
- PyObject *
- gdbpy_lookup_symbol (PyObject *self, PyObject *args, PyObject *kw)
- {
- int domain = VAR_DOMAIN;
- struct field_of_this_result is_a_field_of_this;
- const char *name;
- static const char *keywords[] = { "name", "block", "domain", NULL };
- struct symbol *symbol = NULL;
- PyObject *block_obj = NULL, *sym_obj, *bool_obj;
- const struct block *block = NULL;
- if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|O!i", keywords, &name,
- &block_object_type, &block_obj,
- &domain))
- return NULL;
- if (block_obj)
- block = block_object_to_block (block_obj);
- else
- {
- struct frame_info *selected_frame;
- try
- {
- selected_frame = get_selected_frame (_("No frame selected."));
- block = get_frame_block (selected_frame, NULL);
- }
- catch (const gdb_exception &except)
- {
- GDB_PY_HANDLE_EXCEPTION (except);
- }
- }
- try
- {
- symbol = lookup_symbol (name, block, (domain_enum) domain,
- &is_a_field_of_this).symbol;
- }
- catch (const gdb_exception &except)
- {
- GDB_PY_HANDLE_EXCEPTION (except);
- }
- gdbpy_ref<> ret_tuple (PyTuple_New (2));
- if (ret_tuple == NULL)
- return NULL;
- if (symbol)
- {
- sym_obj = symbol_to_symbol_object (symbol);
- if (!sym_obj)
- return NULL;
- }
- else
- {
- sym_obj = Py_None;
- Py_INCREF (Py_None);
- }
- PyTuple_SET_ITEM (ret_tuple.get (), 0, sym_obj);
- bool_obj = (is_a_field_of_this.type != NULL) ? Py_True : Py_False;
- Py_INCREF (bool_obj);
- PyTuple_SET_ITEM (ret_tuple.get (), 1, bool_obj);
- return ret_tuple.release ();
- }
- /* Implementation of
- gdb.lookup_global_symbol (name [, domain]) -> symbol or None. */
- PyObject *
- gdbpy_lookup_global_symbol (PyObject *self, PyObject *args, PyObject *kw)
- {
- int domain = VAR_DOMAIN;
- const char *name;
- static const char *keywords[] = { "name", "domain", NULL };
- struct symbol *symbol = NULL;
- PyObject *sym_obj;
- if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|i", keywords, &name,
- &domain))
- return NULL;
- try
- {
- symbol = lookup_global_symbol (name, NULL, (domain_enum) domain).symbol;
- }
- catch (const gdb_exception &except)
- {
- GDB_PY_HANDLE_EXCEPTION (except);
- }
- if (symbol)
- {
- sym_obj = symbol_to_symbol_object (symbol);
- if (!sym_obj)
- return NULL;
- }
- else
- {
- sym_obj = Py_None;
- Py_INCREF (Py_None);
- }
- return sym_obj;
- }
- /* Implementation of
- gdb.lookup_static_symbol (name [, domain]) -> symbol or None. */
- PyObject *
- gdbpy_lookup_static_symbol (PyObject *self, PyObject *args, PyObject *kw)
- {
- const char *name;
- int domain = VAR_DOMAIN;
- static const char *keywords[] = { "name", "domain", NULL };
- struct symbol *symbol = NULL;
- PyObject *sym_obj;
- if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|i", keywords, &name,
- &domain))
- return NULL;
- /* In order to find static symbols associated with the "current" object
- file ahead of those from other object files, we first need to see if
- we can acquire a current block. If this fails however, then we still
- want to search all static symbols, so don't throw an exception just
- yet. */
- const struct block *block = NULL;
- try
- {
- struct frame_info *selected_frame
- = get_selected_frame (_("No frame selected."));
- block = get_frame_block (selected_frame, NULL);
- }
- catch (const gdb_exception &except)
- {
- /* Nothing. */
- }
- try
- {
- if (block != nullptr)
- symbol
- = lookup_symbol_in_static_block (name, block,
- (domain_enum) domain).symbol;
- if (symbol == nullptr)
- symbol = lookup_static_symbol (name, (domain_enum) domain).symbol;
- }
- catch (const gdb_exception &except)
- {
- GDB_PY_HANDLE_EXCEPTION (except);
- }
- if (symbol)
- {
- sym_obj = symbol_to_symbol_object (symbol);
- if (!sym_obj)
- return NULL;
- }
- else
- {
- sym_obj = Py_None;
- Py_INCREF (Py_None);
- }
- return sym_obj;
- }
- /* Implementation of
- gdb.lookup_static_symbols (name [, domain]) -> symbol list.
- Returns a list of all static symbols matching NAME in DOMAIN. */
- PyObject *
- gdbpy_lookup_static_symbols (PyObject *self, PyObject *args, PyObject *kw)
- {
- const char *name;
- int domain = VAR_DOMAIN;
- static const char *keywords[] = { "name", "domain", NULL };
- if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s|i", keywords, &name,
- &domain))
- return NULL;
- gdbpy_ref<> return_list (PyList_New (0));
- if (return_list == NULL)
- return NULL;
- try
- {
- /* Expand any symtabs that contain potentially matching symbols. */
- lookup_name_info lookup_name (name, symbol_name_match_type::FULL);
- expand_symtabs_matching (NULL, lookup_name, NULL, NULL,
- SEARCH_GLOBAL_BLOCK | SEARCH_STATIC_BLOCK,
- ALL_DOMAIN);
- for (objfile *objfile : current_program_space->objfiles ())
- {
- for (compunit_symtab *cust : objfile->compunits ())
- {
- const struct blockvector *bv;
- const struct block *block;
- bv = cust->blockvector ();
- block = BLOCKVECTOR_BLOCK (bv, STATIC_BLOCK);
- if (block != nullptr)
- {
- symbol *symbol = lookup_symbol_in_static_block
- (name, block, (domain_enum) domain).symbol;
- if (symbol != nullptr)
- {
- PyObject *sym_obj
- = symbol_to_symbol_object (symbol);
- if (PyList_Append (return_list.get (), sym_obj) == -1)
- return NULL;
- }
- }
- }
- }
- }
- catch (const gdb_exception &except)
- {
- GDB_PY_HANDLE_EXCEPTION (except);
- }
- return return_list.release ();
- }
- /* This function is called when an objfile is about to be freed.
- Invalidate the symbol as further actions on the symbol would result
- in bad data. All access to obj->symbol should be gated by
- SYMPY_REQUIRE_VALID which will raise an exception on invalid
- symbols. */
- static void
- del_objfile_symbols (struct objfile *objfile, void *datum)
- {
- symbol_object *obj = (symbol_object *) datum;
- while (obj)
- {
- symbol_object *next = obj->next;
- obj->symbol = NULL;
- obj->next = NULL;
- obj->prev = NULL;
- obj = next;
- }
- }
- void _initialize_py_symbol ();
- void
- _initialize_py_symbol ()
- {
- /* Register an objfile "free" callback so we can properly
- invalidate symbol when an object file that is about to be
- deleted. */
- sympy_objfile_data_key
- = register_objfile_data_with_cleanup (NULL, del_objfile_symbols);
- }
- int
- gdbpy_initialize_symbols (void)
- {
- if (PyType_Ready (&symbol_object_type) < 0)
- return -1;
- if (PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_UNDEF", LOC_UNDEF) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_CONST",
- LOC_CONST) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_STATIC",
- LOC_STATIC) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REGISTER",
- LOC_REGISTER) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_ARG",
- LOC_ARG) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REF_ARG",
- LOC_REF_ARG) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_LOCAL",
- LOC_LOCAL) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_TYPEDEF",
- LOC_TYPEDEF) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_LABEL",
- LOC_LABEL) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_BLOCK",
- LOC_BLOCK) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_CONST_BYTES",
- LOC_CONST_BYTES) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_UNRESOLVED",
- LOC_UNRESOLVED) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_OPTIMIZED_OUT",
- LOC_OPTIMIZED_OUT) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_COMPUTED",
- LOC_COMPUTED) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_COMMON_BLOCK",
- LOC_COMMON_BLOCK) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LOC_REGPARM_ADDR",
- LOC_REGPARM_ADDR) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_UNDEF_DOMAIN",
- UNDEF_DOMAIN) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_VAR_DOMAIN",
- VAR_DOMAIN) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_STRUCT_DOMAIN",
- STRUCT_DOMAIN) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_LABEL_DOMAIN",
- LABEL_DOMAIN) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_MODULE_DOMAIN",
- MODULE_DOMAIN) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_COMMON_BLOCK_DOMAIN",
- COMMON_BLOCK_DOMAIN) < 0)
- return -1;
- /* These remain defined for compatibility, but as they were never
- correct, they are no longer documented. Eventually we can remove
- them. These exist because at one time, enum search_domain and
- enum domain_enum_tag were combined -- but different values were
- used differently. Here we try to give them values that will make
- sense if they are passed to gdb.lookup_symbol. */
- if (PyModule_AddIntConstant (gdb_module, "SYMBOL_VARIABLES_DOMAIN",
- VAR_DOMAIN) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_FUNCTIONS_DOMAIN",
- VAR_DOMAIN) < 0
- || PyModule_AddIntConstant (gdb_module, "SYMBOL_TYPES_DOMAIN",
- VAR_DOMAIN) < 0)
- return -1;
- return gdb_pymodule_addobject (gdb_module, "Symbol",
- (PyObject *) &symbol_object_type);
- }
- static gdb_PyGetSetDef symbol_object_getset[] = {
- { "type", sympy_get_type, NULL,
- "Type of the symbol.", NULL },
- { "symtab", sympy_get_symtab, NULL,
- "Symbol table in which the symbol appears.", NULL },
- { "name", sympy_get_name, NULL,
- "Name of the symbol, as it appears in the source code.", NULL },
- { "linkage_name", sympy_get_linkage_name, NULL,
- "Name of the symbol, as used by the linker (i.e., may be mangled).",
- NULL },
- { "print_name", sympy_get_print_name, NULL,
- "Name of the symbol in a form suitable for output.\n\
- This is either name or linkage_name, depending on whether the user asked GDB\n\
- to display demangled or mangled names.", NULL },
- { "addr_class", sympy_get_addr_class, NULL, "Address class of the symbol." },
- { "is_argument", sympy_is_argument, NULL,
- "True if the symbol is an argument of a function." },
- { "is_constant", sympy_is_constant, NULL,
- "True if the symbol is a constant." },
- { "is_function", sympy_is_function, NULL,
- "True if the symbol is a function or method." },
- { "is_variable", sympy_is_variable, NULL,
- "True if the symbol is a variable." },
- { "needs_frame", sympy_needs_frame, NULL,
- "True if the symbol requires a frame for evaluation." },
- { "line", sympy_line, NULL,
- "The source line number at which the symbol was defined." },
- { NULL } /* Sentinel */
- };
- static PyMethodDef symbol_object_methods[] = {
- { "is_valid", sympy_is_valid, METH_NOARGS,
- "is_valid () -> Boolean.\n\
- Return true if this symbol is valid, false if not." },
- { "value", sympy_value, METH_VARARGS,
- "value ([frame]) -> gdb.Value\n\
- Return the value of the symbol." },
- {NULL} /* Sentinel */
- };
- PyTypeObject symbol_object_type = {
- PyVarObject_HEAD_INIT (NULL, 0)
- "gdb.Symbol", /*tp_name*/
- sizeof (symbol_object), /*tp_basicsize*/
- 0, /*tp_itemsize*/
- sympy_dealloc, /*tp_dealloc*/
- 0, /*tp_print*/
- 0, /*tp_getattr*/
- 0, /*tp_setattr*/
- 0, /*tp_compare*/
- 0, /*tp_repr*/
- 0, /*tp_as_number*/
- 0, /*tp_as_sequence*/
- 0, /*tp_as_mapping*/
- 0, /*tp_hash */
- 0, /*tp_call*/
- sympy_str, /*tp_str*/
- 0, /*tp_getattro*/
- 0, /*tp_setattro*/
- 0, /*tp_as_buffer*/
- Py_TPFLAGS_DEFAULT, /*tp_flags*/
- "GDB symbol object", /*tp_doc */
- 0, /*tp_traverse */
- 0, /*tp_clear */
- 0, /*tp_richcompare */
- 0, /*tp_weaklistoffset */
- 0, /*tp_iter */
- 0, /*tp_iternext */
- symbol_object_methods, /*tp_methods */
- 0, /*tp_members */
- symbol_object_getset /*tp_getset */
- };
|