xref: /dragonfly/contrib/gdb-7/gdb/python/lib/gdb/types.py (revision 4d0c54c1)
1# Type utilities.
2# Copyright (C) 2010-2012 Free Software Foundation, Inc.
3
4# This program is free software; you can redistribute it and/or modify
5# it under the terms of the GNU General Public License as published by
6# the Free Software Foundation; either version 3 of the License, or
7# (at your option) any later version.
8#
9# This program is distributed in the hope that it will be useful,
10# but WITHOUT ANY WARRANTY; without even the implied warranty of
11# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12# GNU General Public License for more details.
13#
14# You should have received a copy of the GNU General Public License
15# along with this program.  If not, see <http://www.gnu.org/licenses/>.
16
17"""Utilities for working with gdb.Types."""
18
19import gdb
20
21
22def get_basic_type(type_):
23    """Return the "basic" type of a type.
24
25    Arguments:
26        type_: The type to reduce to its basic type.
27
28    Returns:
29        type_ with const/volatile is stripped away,
30        and typedefs/references converted to the underlying type.
31    """
32
33    while (type_.code == gdb.TYPE_CODE_REF or
34           type_.code == gdb.TYPE_CODE_TYPEDEF):
35        if type_.code == gdb.TYPE_CODE_REF:
36            type_ = type_.target()
37        else:
38            type_ = type_.strip_typedefs()
39    return type_.unqualified()
40
41
42def has_field(type_, field):
43    """Return True if a type has the specified field.
44
45    Arguments:
46        type_: The type to examine.
47            It must be one of gdb.TYPE_CODE_STRUCT, gdb.TYPE_CODE_UNION.
48        field: The name of the field to look up.
49
50    Returns:
51        True if the field is present either in type_ or any baseclass.
52
53    Raises:
54        TypeError: The type is not a struct or union.
55    """
56
57    type_ = get_basic_type(type_)
58    if (type_.code != gdb.TYPE_CODE_STRUCT and
59        type_.code != gdb.TYPE_CODE_UNION):
60        raise TypeError("not a struct or union")
61    for f in type_.fields():
62        if f.is_base_class:
63            if has_field(f.type, field):
64                return True
65        else:
66            # NOTE: f.name could be None
67            if f.name == field:
68                return True
69    return False
70
71
72def make_enum_dict(enum_type):
73    """Return a dictionary from a program's enum type.
74
75    Arguments:
76        enum_type: The enum to compute the dictionary for.
77
78    Returns:
79        The dictionary of the enum.
80
81    Raises:
82        TypeError: The type is not an enum.
83    """
84
85    if enum_type.code != gdb.TYPE_CODE_ENUM:
86        raise TypeError("not an enum type")
87    enum_dict = {}
88    for field in enum_type.fields():
89        # The enum's value is stored in "bitpos".
90        enum_dict[field.name] = field.bitpos
91    return enum_dict
92
93
94def deep_items (type_):
95    """Return an iterator that recursively traverses anonymous fields.
96
97    Arguments:
98        type_: The type to traverse.  It should be one of
99        gdb.TYPE_CODE_STRUCT or gdb.TYPE_CODE_UNION.
100
101    Returns:
102        an iterator similar to gdb.Type.iteritems(), i.e., it returns
103        pairs of key, value, but for any anonymous struct or union
104        field that field is traversed recursively, depth-first.
105    """
106    for k, v in type_.iteritems ():
107        if k:
108            yield k, v
109        else:
110            for i in deep_items (v.type):
111                yield i
112