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