GDB (API)
/home/stan/gdb/src/gdb/python/lib/gdb/types.py
Go to the documentation of this file.
00001 # Type utilities.
00002 # Copyright (C) 2010-2013 Free Software Foundation, Inc.
00003 
00004 # This program is free software; you can redistribute it and/or modify
00005 # it under the terms of the GNU General Public License as published by
00006 # the Free Software Foundation; either version 3 of the License, or
00007 # (at your option) any later version.
00008 #
00009 # This program is distributed in the hope that it will be useful,
00010 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00011 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012 # GNU General Public License for more details.
00013 #
00014 # You should have received a copy of the GNU General Public License
00015 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
00016 
00017 """Utilities for working with gdb.Types."""
00018 
00019 import gdb
00020 
00021 
00022 def get_basic_type(type_):
00023     """Return the "basic" type of a type.
00024 
00025     Arguments:
00026         type_: The type to reduce to its basic type.
00027 
00028     Returns:
00029         type_ with const/volatile is stripped away,
00030         and typedefs/references converted to the underlying type.
00031     """
00032 
00033     while (type_.code == gdb.TYPE_CODE_REF or
00034            type_.code == gdb.TYPE_CODE_TYPEDEF):
00035         if type_.code == gdb.TYPE_CODE_REF:
00036             type_ = type_.target()
00037         else:
00038             type_ = type_.strip_typedefs()
00039     return type_.unqualified()
00040 
00041 
00042 def has_field(type_, field):
00043     """Return True if a type has the specified field.
00044 
00045     Arguments:
00046         type_: The type to examine.
00047             It must be one of gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_UNION.
00048         field: The name of the field to look up.
00049 
00050     Returns:
00051         True if the field is present either in type_ or any baseclass.
00052 
00053     Raises:
00054         TypeError: The type is not a struct or union.
00055     """
00056 
00057     type_ = get_basic_type(type_)
00058     if (type_.code != gdb.TYPE_CODE_STRUCT and
00059         type_.code != gdb.TYPE_CODE_UNION):
00060         raise TypeError("not a struct or union")
00061     for f in type_.fields():
00062         if f.is_base_class:
00063             if has_field(f.type, field):
00064                 return True
00065         else:
00066             # NOTE: f.name could be None
00067             if f.name == field:
00068                 return True
00069     return False
00070 
00071 
00072 def make_enum_dict(enum_type):
00073     """Return a dictionary from a program's enum type.
00074 
00075     Arguments:
00076         enum_type: The enum to compute the dictionary for.
00077 
00078     Returns:
00079         The dictionary of the enum.
00080 
00081     Raises:
00082         TypeError: The type is not an enum.
00083     """
00084 
00085     if enum_type.code != gdb.TYPE_CODE_ENUM:
00086         raise TypeError("not an enum type")
00087     enum_dict = {}
00088     for field in enum_type.fields():
00089         # The enum's value is stored in "enumval".
00090         enum_dict[field.name] = field.enumval
00091     return enum_dict
00092 
00093 
00094 def deep_items (type_):
00095     """Return an iterator that recursively traverses anonymous fields.
00096 
00097     Arguments:
00098         type_: The type to traverse.  It should be one of
00099         gdb.TYPE_CODE_STRUCT or gdb.TYPE_CODE_UNION.
00100 
00101     Returns:
00102         an iterator similar to gdb.Type.iteritems(), i.e., it returns
00103         pairs of key, value, but for any anonymous struct or union
00104         field that field is traversed recursively, depth-first.
00105     """
00106     for k, v in type_.iteritems ():
00107         if k:
00108             yield k, v
00109         else:
00110             for i in deep_items (v.type):
00111                 yield i
00112 
00113 class TypePrinter(object):
00114     """The base class for type printers.
00115 
00116     Instances of this type can be used to substitute type names during
00117     'ptype'.
00118 
00119     A type printer must have at least 'name' and 'enabled' attributes,
00120     and supply an 'instantiate' method.
00121 
00122     The 'instantiate' method must either return None, or return an
00123     object which has a 'recognize' method.  This method must accept a
00124     gdb.Type argument and either return None, meaning that the type
00125     was not recognized, or a string naming the type.
00126     """
00127 
00128     def __init__(self, name):
00129         self.name = name
00130         self.enabled = True
00131 
00132     def instantiate(self):
00133         return None
00134 
00135 # Helper function for computing the list of type recognizers.
00136 def _get_some_type_recognizers(result, plist):
00137     for printer in plist:
00138         if printer.enabled:
00139             inst = printer.instantiate()
00140             if inst is not None:
00141                 result.append(inst)
00142     return None
00143 
00144 def get_type_recognizers():
00145     "Return a list of the enabled type recognizers for the current context."
00146     result = []
00147 
00148     # First try the objfiles.
00149     for objfile in gdb.objfiles():
00150         _get_some_type_recognizers(result, objfile.type_printers)
00151     # Now try the program space.
00152     _get_some_type_recognizers(result, gdb.current_progspace().type_printers)
00153     # Finally, globals.
00154     _get_some_type_recognizers(result, gdb.type_printers)
00155 
00156     return result
00157 
00158 def apply_type_recognizers(recognizers, type_obj):
00159     """Apply the given list of type recognizers to the type TYPE_OBJ.
00160     If any recognizer in the list recognizes TYPE_OBJ, returns the name
00161     given by the recognizer.  Otherwise, this returns None."""
00162     for r in recognizers:
00163         result = r.recognize(type_obj)
00164         if result is not None:
00165             return result
00166     return None
00167 
00168 def register_type_printer(locus, printer):
00169     """Register a type printer.
00170     PRINTER is the type printer instance.
00171     LOCUS is either an objfile, a program space, or None, indicating
00172     global registration."""
00173 
00174     if locus is None:
00175         locus = gdb
00176     locus.type_printers.insert(0, printer)
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines