mirror of
https://github.com/JakeHillion/drgn.git
synced 2024-12-23 17:53:07 +00:00
type: add Type.unqualified()
This commit is contained in:
parent
9b5b721838
commit
6fa2d68c0c
39
drgn/type.py
39
drgn/type.py
@ -164,12 +164,18 @@ class Type:
|
||||
"""
|
||||
return self
|
||||
|
||||
def unqualified(self) -> 'Type':
|
||||
"""
|
||||
Return this type without qualifiers.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def operand_type(self) -> 'Type':
|
||||
"""
|
||||
Return the type that this type is converted to when used in an
|
||||
expression.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
return self.unqualified()
|
||||
|
||||
def is_arithmetic(self) -> bool:
|
||||
"""
|
||||
@ -217,7 +223,7 @@ class VoidType(Type):
|
||||
def convert(self, value: Any) -> None:
|
||||
return None
|
||||
|
||||
def operand_type(self) -> 'VoidType':
|
||||
def unqualified(self) -> 'VoidType':
|
||||
if self.qualifiers:
|
||||
return VoidType()
|
||||
return self
|
||||
@ -310,7 +316,7 @@ class IntType(ArithmeticType):
|
||||
raise TypeError(f'cannot convert to {self}')
|
||||
return _int_convert(math.trunc(value), 8 * self.size, self.signed)
|
||||
|
||||
def operand_type(self) -> 'IntType':
|
||||
def unqualified(self) -> 'IntType':
|
||||
if self.qualifiers:
|
||||
return IntType(self.name, self.size, self.signed)
|
||||
return self
|
||||
@ -346,7 +352,7 @@ class BoolType(IntType):
|
||||
raise TypeError(f'cannot convert to {self}')
|
||||
return bool(value)
|
||||
|
||||
def operand_type(self) -> 'BoolType':
|
||||
def unqualified(self) -> 'BoolType':
|
||||
if self.qualifiers:
|
||||
return BoolType(self.name, self.size)
|
||||
return self
|
||||
@ -375,7 +381,7 @@ class FloatType(ArithmeticType):
|
||||
else:
|
||||
raise ValueError(f"can't convert to float of size {self.size}")
|
||||
|
||||
def operand_type(self) -> 'FloatType':
|
||||
def unqualified(self) -> 'FloatType':
|
||||
if self.qualifiers:
|
||||
return FloatType(self.name, self.size)
|
||||
return self
|
||||
@ -457,9 +463,9 @@ class BitFieldType(Type):
|
||||
raise TypeError(f'cannot convert to {self}')
|
||||
return _int_convert(math.trunc(value), self.bit_size, self.type.signed)
|
||||
|
||||
def operand_type(self) -> 'BitFieldType':
|
||||
def unqualified(self) -> 'BitFieldType':
|
||||
if self.type.qualifiers:
|
||||
return BitFieldType(self.type.operand_type(), self.bit_offset,
|
||||
return BitFieldType(self.type.unqualified(), self.bit_offset,
|
||||
self.bit_size)
|
||||
return self
|
||||
|
||||
@ -656,7 +662,7 @@ class StructType(CompoundType):
|
||||
def type_name(self) -> StructTypeName:
|
||||
return StructTypeName(self.name, self.qualifiers)
|
||||
|
||||
def operand_type(self) -> 'StructType':
|
||||
def unqualified(self) -> 'StructType':
|
||||
if self.qualifiers:
|
||||
return StructType(self.name, self.size, self._members)
|
||||
return self
|
||||
@ -684,7 +690,7 @@ class UnionType(CompoundType):
|
||||
def type_name(self) -> UnionTypeName:
|
||||
return UnionTypeName(self.name, self.qualifiers)
|
||||
|
||||
def operand_type(self) -> 'UnionType':
|
||||
def unqualified(self) -> 'UnionType':
|
||||
if self.qualifiers:
|
||||
return UnionType(self.name, self.size, self._members)
|
||||
return self
|
||||
@ -806,7 +812,7 @@ class EnumType(Type):
|
||||
pass
|
||||
return value
|
||||
|
||||
def operand_type(self) -> 'EnumType':
|
||||
def unqualified(self) -> 'EnumType':
|
||||
if self.qualifiers:
|
||||
return EnumType(self.name, self.type,
|
||||
None if self.enum is None else self.enum.__members__)
|
||||
@ -883,6 +889,11 @@ class TypedefType(Type):
|
||||
type_ = type_.type
|
||||
return type_
|
||||
|
||||
def unqualified(self) -> 'TypedefType':
|
||||
if self.qualifiers:
|
||||
return TypedefType(self.name, self.type)
|
||||
return self
|
||||
|
||||
def operand_type(self) -> Type:
|
||||
type_ = self.type
|
||||
while isinstance(type_, TypedefType):
|
||||
@ -957,7 +968,7 @@ class PointerType(Type):
|
||||
raise TypeError(f'cannot convert to {self}')
|
||||
return _int_convert(int(value), 8 * self.size, False)
|
||||
|
||||
def operand_type(self) -> 'PointerType':
|
||||
def unqualified(self) -> 'PointerType':
|
||||
if self.qualifiers:
|
||||
return PointerType(self.size, self.type)
|
||||
return self
|
||||
@ -1041,6 +1052,9 @@ class ArrayType(Type):
|
||||
parts.append('}')
|
||||
return ''.join(parts)
|
||||
|
||||
def unqualified(self) -> 'ArrayType':
|
||||
return self
|
||||
|
||||
def operand_type(self) -> 'PointerType':
|
||||
return PointerType(self.pointer_size, self.type)
|
||||
|
||||
@ -1103,6 +1117,9 @@ class FunctionType(Type):
|
||||
def pretty(self, value: Any, cast: bool = True) -> str:
|
||||
raise ValueError("can't format function")
|
||||
|
||||
def unqualified(self) -> 'FunctionType':
|
||||
return self
|
||||
|
||||
def operand_type(self) -> 'PointerType':
|
||||
return PointerType(self.pointer_size, self)
|
||||
|
||||
|
@ -545,29 +545,38 @@ class TestConvert(unittest.TestCase):
|
||||
self.assertEqual(type_.convert(2**64 + 1), 1)
|
||||
|
||||
|
||||
class TestOperandType(TypeTestCase):
|
||||
class TestUnqualifiedAndOperandType(TypeTestCase):
|
||||
def assertUnqualifiedType(self, type_, expected):
|
||||
for i in range(2):
|
||||
type_ = type_.unqualified()
|
||||
self.assertEqual(type_, expected)
|
||||
|
||||
def assertOperandType(self, type_, expected):
|
||||
for i in range(2):
|
||||
type_ = type_.operand_type()
|
||||
self.assertEqual(type_, expected)
|
||||
|
||||
def assertBoth(self, type_, expected):
|
||||
self.assertUnqualifiedType(type_, expected)
|
||||
self.assertOperandType(type_, expected)
|
||||
|
||||
def test_void(self):
|
||||
self.assertOperandType(VoidType(frozenset({'const'})), VoidType())
|
||||
self.assertBoth(VoidType(frozenset({'const'})), VoidType())
|
||||
|
||||
def test_int(self):
|
||||
self.assertOperandType(IntType('int', 4, True, frozenset({'const'})),
|
||||
self.assertBoth(IntType('int', 4, True, frozenset({'const'})),
|
||||
IntType('int', 4, True))
|
||||
|
||||
def test_bool(self):
|
||||
self.assertOperandType(BoolType('_Bool', 1, frozenset({'const'})),
|
||||
self.assertBoth(BoolType('_Bool', 1, frozenset({'const'})),
|
||||
BoolType('_Bool', 1))
|
||||
|
||||
def test_float(self):
|
||||
self.assertOperandType(FloatType('double', 8, frozenset({'const'})),
|
||||
self.assertBoth(FloatType('double', 8, frozenset({'const'})),
|
||||
FloatType('double', 8))
|
||||
|
||||
def test_bit_field(self):
|
||||
self.assertOperandType(BitFieldType(IntType('int', 4, True, frozenset({'const'})), 0, 4),
|
||||
self.assertBoth(BitFieldType(IntType('int', 4, True, frozenset({'const'})), 0, 4),
|
||||
BitFieldType(IntType('int', 4, True), 0, 4))
|
||||
|
||||
def test_struct(self):
|
||||
@ -575,7 +584,7 @@ class TestOperandType(TypeTestCase):
|
||||
('x', 0, lambda: IntType('int', 4, True)),
|
||||
('y', 4, lambda: IntType('int', 4, True)),
|
||||
], frozenset({'const'}))
|
||||
self.assertOperandType(const_point_type, point_type)
|
||||
self.assertBoth(const_point_type, point_type)
|
||||
|
||||
def test_union(self):
|
||||
union_type = UnionType('value', 4, [
|
||||
@ -586,7 +595,7 @@ class TestOperandType(TypeTestCase):
|
||||
('i', 0, lambda: IntType('int', 4, True)),
|
||||
('f', 0, lambda: FloatType('float', 4)),
|
||||
], frozenset({'const'}))
|
||||
self.assertOperandType(const_union_type, union_type)
|
||||
self.assertBoth(const_union_type, union_type)
|
||||
|
||||
def test_enum(self):
|
||||
enum_type = EnumType(None, IntType('int', 4, True), [
|
||||
@ -599,7 +608,7 @@ class TestOperandType(TypeTestCase):
|
||||
('GREEN', 11),
|
||||
('BLUE', -1)
|
||||
], frozenset({'const'}))
|
||||
self.assertOperandType(const_enum_type, enum_type)
|
||||
self.assertBoth(const_enum_type, enum_type)
|
||||
|
||||
def test_typedef(self):
|
||||
const_typedef_type = TypedefType(
|
||||
@ -610,9 +619,14 @@ class TestOperandType(TypeTestCase):
|
||||
frozenset({'const'}))
|
||||
typedef_type = TypedefType('u32', IntType('unsigned int', 4, False))
|
||||
|
||||
self.assertUnqualifiedType(const_typedef_type, typedef_type)
|
||||
self.assertOperandType(const_typedef_type, typedef_type)
|
||||
|
||||
self.assertUnqualifiedType(typedef_const_type, typedef_const_type)
|
||||
self.assertOperandType(typedef_const_type,
|
||||
IntType('unsigned int', 4, False))
|
||||
|
||||
self.assertUnqualifiedType(const_typedef_const_type, typedef_const_type)
|
||||
self.assertOperandType(const_typedef_const_type,
|
||||
IntType('unsigned int', 4, False))
|
||||
|
||||
@ -630,16 +644,20 @@ class TestOperandType(TypeTestCase):
|
||||
|
||||
def test_array(self):
|
||||
type_ = ArrayType(IntType('int', 4, True), 2, pointer_size)
|
||||
self.assertUnqualifiedType(type_, type_)
|
||||
self.assertOperandType(type_, PointerType(pointer_size, type_.type))
|
||||
|
||||
typedef_type = TypedefType('pair_t', type_)
|
||||
self.assertUnqualifiedType(typedef_type, typedef_type)
|
||||
self.assertOperandType(typedef_type, PointerType(pointer_size, type_.type))
|
||||
|
||||
def test_function(self):
|
||||
type_ = FunctionType(pointer_size, VoidType, [])
|
||||
self.assertUnqualifiedType(type_, type_)
|
||||
self.assertOperandType(type_, PointerType(pointer_size, type_))
|
||||
|
||||
typedef_type = TypedefType('callback_t', type_)
|
||||
self.assertUnqualifiedType(typedef_type, typedef_type)
|
||||
self.assertOperandType(typedef_type, PointerType(pointer_size, type_))
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user