tools/gdb/util/class_methods.py
def Class(class_name, template_types):
  """Decorate a python class with its corresponding C++ type.
  Args:
    class_name: The canonical string identifier for the class (e.g. base::Foo)
    template_types: An array of names for each templated type (e.g. ['K',
    'V'])

  Example:
    As an example, the following is an implementation of size() and operator[]
    on std::__1::vector, functions which are normally inlined and not
    normally callable from gdb.

    @class_methods.Class('std::__1::vector', template_types=['T'])
    class LibcppVector(object):
      @class_methods.member_function('T&', 'operator[]', ['int'])
      def element(obj, i):
        return obj['__begin_'][i]

      @class_methods.member_function('size_t', 'size', [])
      def size(obj):
        return obj['__end_'] - obj['__begin_']

  Note:
    Note that functions are looked up by the function name, which means that
    functions cannot currently have overloaded implementations for different
    arguments.
  """

  class MethodWorkerWrapper(gdb.xmethod.XMethod):
    """Wrapper of an XMethodWorker class as an XMethod."""
    def __init__(self, name, worker_class):
      super(MethodWorkerWrapper, self).__init__(name)
      self.name = name
      self.worker_class = worker_class


  class ClassMatcher(gdb.xmethod.XMethodMatcher):
    """Matches member functions of one class template."""
    def __init__(self, obj):
      super(ClassMatcher, self).__init__(class_name)

      # Constructs a regular expression to match this type.
      self._class_regex = re.compile(
          '^' + re.escape(class_name) +
          ('<.*>' if len(template_types) > 0 else '') + '$')

      # Construct a dictionary and array of methods
      self.dict = {}
      self.methods = []
      for name in dir(obj):
        attr = getattr(obj, name)
        if not isinstance(attr, MemberFunction):
          continue

        name = attr.name
        return_type = CreateTypeResolver(attr.return_type)
        arguments = [CreateTypeResolver(arg) for arg in
                     attr.arguments]
        method = MethodWorkerWrapper(
            attr.name,
            CreateTemplatedMethodWorker(return_type,
                                        arguments, attr.function_))
        self.methods.append(method)

    def match(self, class_type, method_name):
      if not re.match(self._class_regex, class_type.tag):
        return None
      templates = [class_type.template_argument(i) for i in
                   range(len(template_types))]
      return [method.worker_class(templates) for method in self.methods
              if method.name == method_name and method.enabled]


  def CreateTypeResolver(type_desc):
    """Creates a callback which resolves to the appropriate type when
    invoked.

    This is a helper to allow specifying simple types as strings when
    writing function descriptions. For complex cases, a callback can be
    passed which will be invoked when template instantiation is known.

    Args:
      type_desc: A callback generating the type or a string description of
          the type to lookup. Supported types are classes in the
          template_classes array (e.g. T) which will be looked up when those
          templated classes are known, or globally visible type names (e.g.
          int, base::Foo).

          Types can be modified by appending a '*' or '&' to denote a
          pointer or reference.

          If a callback is used, the callback will be passed an array of the
          instantiated template types.

    Note:
      This does not parse complex types such as std::vector<T>::iterator,
      to refer to types like these you must currently write a callback
      which constructs the appropriate type.
    """
    if callable(type_desc):
      return type_desc
    if type_desc == 'void':
      return lambda T: None
    if type_desc[-1] == '&':
      inner_resolver = CreateTypeResolver(type_desc[:-1])
      return lambda template_types: inner_resolver(template_types).reference()
    if type_desc[-1] == '*':
      inner_resolver = CreateTypeResolver(type_desc[:-1])
      return lambda template_types: inner_resolver(template_types).pointer()
    try:
      template_index = template_types.index(type_desc)
      return operator.itemgetter(template_index)
    except ValueError:
      return lambda template_types: gdb.lookup_type(type_desc)


  def CreateTemplatedMethodWorker(return_callback, args_callbacks,
                                  method_callback):
    class TemplatedMethodWorker(gdb.xmethod.XMethodWorker):
      def __init__(self, templates):
        super(TemplatedMethodWorker, self).__init__()
        self._templates = templates

      def get_arg_types(self):
        return [cb(self._templates) for cb in args_callbacks]

      def get_result_type(self, obj):
        return return_callback(self._templates)

      def __call__(self, *args):
        return method_callback(*args)
    return TemplatedMethodWorker

  def DefineClass(obj):
    matcher = ClassMatcher(obj)
    gdb.xmethod.register_xmethod_matcher(None, matcher)
    return matcher

  return DefineClass
Decorate a python class with its corresponding C++ type.
  Args:
    class_name: The canonical string identifier for the class (e.g. base::Foo)
    template_types: An array of names for each templated type (e.g. ['K',
    'V'])

  Example:
    As an example, the following is an implementation of size() and operator[]
    on std::__1::vector, functions which are normally inlined and not
    normally callable from gdb.

    @class_methods.Class('std::__1::vector', template_types=['T'])
    class LibcppVector(object):
      @class_methods.member_function('T&', 'operator[]', ['int'])
      def element(obj, i):
        return obj['__begin_'][i]

      @class_methods.member_function('size_t', 'size', [])
      def size(obj):
        return obj['__end_'] - obj['__begin_']

  Note:
    Note that functions are looked up by the function name, which means that
    functions cannot currently have overloaded implementations for different
    arguments.
  
Decorate a python class with its corresponding C++ type.
Args:
class_name: The canonical string identifier for the class
template_types: An array of names for each templated type

As an example, the following is an implementation of size() and operator[]
on std::__1::vector, functions which are normally inlined and not
normally callable from gdb.





Note that functions are looked up by the function name, which means that
functions cannot currently have overloaded implementations for different
arguments.
Decorate a python class with its corresponding C ++ type . Args : class_name : The canonical string identifier for the class template_types : An array of names for each templated type As an example the following is an implementation of size () and operator [] on std :: __1 :: vector functions which are normally inlined and not normally callable from gdb . Note that functions are looked up by the function name which means that functions cannot currently have overloaded implementations for different arguments .
def Class(class_name, template_types):
  class MethodWorkerWrapper(gdb.xmethod.XMethod):
    def __init__(self, name, worker_class):
      super(MethodWorkerWrapper, self).__init__(name)
      self.name = name
      self.worker_class = worker_class
  class ClassMatcher(gdb.xmethod.XMethodMatcher):
    def __init__(self, obj):
      super(ClassMatcher, self).__init__(class_name)
      self._class_regex = re.compile(
          '^' + re.escape(class_name) +
          ('<.*>' if len(template_types) > 0 else '') + '$')
      self.dict = {}
      self.methods = []
      for name in dir(obj):
        attr = getattr(obj, name)
        if not isinstance(attr, MemberFunction):
          continue
        name = attr.name
        return_type = CreateTypeResolver(attr.return_type)
        arguments = [CreateTypeResolver(arg) for arg in
                     attr.arguments]
        method = MethodWorkerWrapper(
            attr.name,
            CreateTemplatedMethodWorker(return_type,
                                        arguments, attr.function_))
        self.methods.append(method)
    def match(self, class_type, method_name):
      if not re.match(self._class_regex, class_type.tag):
        return None
      templates = [class_type.template_argument(i) for i in
                   range(len(template_types))]
      return [method.worker_class(templates) for method in self.methods
              if method.name == method_name and method.enabled]
  def CreateTypeResolver(type_desc):
    if callable(type_desc):
      return type_desc
    if type_desc == 'void':
      return lambda T: None
    if type_desc[-1] == '&':
      inner_resolver = CreateTypeResolver(type_desc[:-1])
      return lambda template_types: inner_resolver(template_types).reference()
    if type_desc[-1] == '*':
      inner_resolver = CreateTypeResolver(type_desc[:-1])
      return lambda template_types: inner_resolver(template_types).pointer()
    try:
      template_index = template_types.index(type_desc)
      return operator.itemgetter(template_index)
    except ValueError:
      return lambda template_types: gdb.lookup_type(type_desc)
  def CreateTemplatedMethodWorker(return_callback, args_callbacks,
                                  method_callback):
    class TemplatedMethodWorker(gdb.xmethod.XMethodWorker):
      def __init__(self, templates):
        super(TemplatedMethodWorker, self).__init__()
        self._templates = templates
      def get_arg_types(self):
        return [cb(self._templates) for cb in args_callbacks]
      def get_result_type(self, obj):
        return return_callback(self._templates)
      def __call__(self, *args):
        return method_callback(*args)
    return TemplatedMethodWorker
  def DefineClass(obj):
    matcher = ClassMatcher(obj)
    gdb.xmethod.register_xmethod_matcher(None, matcher)
    return matcher
  return DefineClass
def Class ( class_name , template_types ) : class MethodWorkerWrapper ( gdb . xmethod . XMethod ) : """Wrapper of an XMethodWorker class as an XMethod.""" def __init__ ( self , name , worker_class ) : super ( MethodWorkerWrapper , self ) . __init__ ( name ) self . name = name self . worker_class = worker_class class ClassMatcher ( gdb . xmethod . XMethodMatcher ) : """Matches member functions of one class template.""" def __init__ ( self , obj ) : super ( ClassMatcher , self ) . __init__ ( class_name ) self . _class_regex = re . compile ( '^' + re . escape ( class_name ) + ( '<.*>' if len ( template_types ) > 0 else '' ) + '$' ) self . dict = { } self . methods = [ ] for name in dir ( obj ) : attr = getattr ( obj , name ) if not isinstance ( attr , MemberFunction ) : continue name = attr . name return_type = CreateTypeResolver ( attr . return_type ) arguments = [ CreateTypeResolver ( arg ) for arg in attr . arguments ] method = MethodWorkerWrapper ( attr . name , CreateTemplatedMethodWorker ( return_type , arguments , attr . function_ ) ) self . methods . append ( method ) def match ( self , class_type , method_name ) : if not re . match ( self . _class_regex , class_type . tag ) : return None templates = [ class_type . template_argument ( i ) for i in range ( len ( template_types ) ) ] return [ method . worker_class ( templates ) for method in self . methods if method . name == method_name and method . enabled ] def CreateTypeResolver ( type_desc ) : """Creates a callback which resolves to the appropriate type when
    invoked.

    This is a helper to allow specifying simple types as strings when
    writing function descriptions. For complex cases, a callback can be
    passed which will be invoked when template instantiation is known.

    Args:
      type_desc: A callback generating the type or a string description of
          the type to lookup. Supported types are classes in the
          template_classes array (e.g. T) which will be looked up when those
          templated classes are known, or globally visible type names (e.g.
          int, base::Foo).

          Types can be modified by appending a '*' or '&' to denote a
          pointer or reference.

          If a callback is used, the callback will be passed an array of the
          instantiated template types.

    Note:
      This does not parse complex types such as std::vector<T>::iterator,
      to refer to types like these you must currently write a callback
      which constructs the appropriate type.
    """ if callable ( type_desc ) : return type_desc if type_desc == 'void' : return lambda T : None if type_desc [ - 1 ] == '&' : inner_resolver = CreateTypeResolver ( type_desc [ : - 1 ] ) return lambda template_types : inner_resolver ( template_types ) . reference ( ) if type_desc [ - 1 ] == '*' : inner_resolver = CreateTypeResolver ( type_desc [ : - 1 ] ) return lambda template_types : inner_resolver ( template_types ) . pointer ( ) try : template_index = template_types . index ( type_desc ) return operator . itemgetter ( template_index ) except ValueError : return lambda template_types : gdb . lookup_type ( type_desc ) def CreateTemplatedMethodWorker ( return_callback , args_callbacks , method_callback ) : class TemplatedMethodWorker ( gdb . xmethod . XMethodWorker ) : def __init__ ( self , templates ) : super ( TemplatedMethodWorker , self ) . __init__ ( ) self . _templates = templates def get_arg_types ( self ) : return [ cb ( self . _templates ) for cb in args_callbacks ] def get_result_type ( self , obj ) : return return_callback ( self . _templates ) def __call__ ( self , * args ) : return method_callback ( * args ) return TemplatedMethodWorker def DefineClass ( obj ) : matcher = ClassMatcher ( obj ) gdb . xmethod . register_xmethod_matcher ( None , matcher ) return matcher return DefineClass
Decorate a python class with its corresponding C++ type.
Decorate a python class with its corresponding C ++ type .
"""Decorate a python class with its corresponding C++ type.
  Args:
    class_name: The canonical string identifier for the class (e.g. base::Foo)
    template_types: An array of names for each templated type (e.g. ['K',
    'V'])

  Example:
    As an example, the following is an implementation of size() and operator[]
    on std::__1::vector, functions which are normally inlined and not
    normally callable from gdb.

    @class_methods.Class('std::__1::vector', template_types=['T'])
    class LibcppVector(object):
      @class_methods.member_function('T&', 'operator[]', ['int'])
      def element(obj, i):
        return obj['__begin_'][i]

      @class_methods.member_function('size_t', 'size', [])
      def size(obj):
        return obj['__end_'] - obj['__begin_']

  Note:
    Note that functions are looked up by the function name, which means that
    functions cannot currently have overloaded implementations for different
    arguments.
  """ """Wrapper of an XMethodWorker class as an XMethod.""" """Matches member functions of one class template.""" # Constructs a regular expression to match this type. # Construct a dictionary and array of methods """Creates a callback which resolves to the appropriate type when
    invoked.

    This is a helper to allow specifying simple types as strings when
    writing function descriptions. For complex cases, a callback can be
    passed which will be invoked when template instantiation is known.

    Args:
      type_desc: A callback generating the type or a string description of
          the type to lookup. Supported types are classes in the
          template_classes array (e.g. T) which will be looked up when those
          templated classes are known, or globally visible type names (e.g.
          int, base::Foo).

          Types can be modified by appending a '*' or '&' to denote a
          pointer or reference.

          If a callback is used, the callback will be passed an array of the
          instantiated template types.

    Note:
      This does not parse complex types such as std::vector<T>::iterator,
      to refer to types like these you must currently write a callback
      which constructs the appropriate type.
    """
class_name
template_types