drgn/tests/test_type.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

1585 lines
54 KiB
Python
Raw Normal View History

# Copyright (c) Facebook, Inc. and its affiliates.
# SPDX-License-Identifier: GPL-3.0+
2020-07-16 00:34:56 +01:00
import operator
from drgn import (
Language,
PrimitiveType,
2020-07-16 00:34:56 +01:00
Program,
Qualifiers,
TypeEnumerator,
TypeKind,
TypeMember,
TypeParameter,
sizeof,
)
2020-07-16 00:34:56 +01:00
from tests import DEFAULT_LANGUAGE, MockProgramTestCase
2020-07-16 00:34:56 +01:00
class TestType(MockProgramTestCase):
def test_void(self):
2020-07-16 00:34:56 +01:00
t = self.prog.void_type()
self.assertEqual(t.kind, TypeKind.VOID)
self.assertEqual(t.primitive, PrimitiveType.C_VOID)
self.assertEqual(t.language, DEFAULT_LANGUAGE)
2020-07-16 00:34:56 +01:00
self.assertEqual(t, self.prog.void_type())
self.assertFalse(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(repr(t), "prog.void_type()")
def test_int(self):
2020-07-16 00:34:56 +01:00
t = self.prog.int_type("int", 4, True)
self.assertEqual(t.kind, TypeKind.INT)
self.assertEqual(t.primitive, PrimitiveType.C_INT)
self.assertEqual(t.language, DEFAULT_LANGUAGE)
self.assertEqual(t.name, "int")
self.assertEqual(t.size, 4)
self.assertTrue(t.is_signed)
self.assertTrue(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(t, self.prog.int_type("int", 4, True))
self.assertNotEqual(t, self.prog.int_type("long", 4, True))
self.assertNotEqual(t, self.prog.int_type("int", 2, True))
self.assertNotEqual(t, self.prog.int_type("int", 4, False))
2020-07-16 00:34:56 +01:00
self.assertEqual(repr(t), "prog.int_type(name='int', size=4, is_signed=True)")
self.assertEqual(sizeof(t), 4)
2020-07-16 00:34:56 +01:00
self.assertRaises(TypeError, self.prog.int_type, None, 4, True)
2020-07-16 00:34:56 +01:00
self.assertIsNone(self.prog.int_type("my_int", 4, True).primitive)
self.assertIsNone(self.prog.int_type("int", 4, False).primitive)
def test_bool(self):
2020-07-16 00:34:56 +01:00
t = self.prog.bool_type("_Bool", 1)
self.assertEqual(t.kind, TypeKind.BOOL)
self.assertEqual(t.primitive, PrimitiveType.C_BOOL)
self.assertEqual(t.language, DEFAULT_LANGUAGE)
self.assertEqual(t.name, "_Bool")
self.assertEqual(t.size, 1)
self.assertTrue(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(t, self.prog.bool_type("_Bool", 1))
self.assertNotEqual(t, self.prog.bool_type("bool", 1))
self.assertNotEqual(t, self.prog.bool_type("_Bool", 2))
2018-07-12 05:51:48 +01:00
2020-07-16 00:34:56 +01:00
self.assertEqual(repr(t), "prog.bool_type(name='_Bool', size=1)")
self.assertEqual(sizeof(t), 1)
2020-07-16 00:34:56 +01:00
self.assertRaises(TypeError, self.prog.bool_type, None, 1)
def test_float(self):
2020-07-16 00:34:56 +01:00
t = self.prog.float_type("float", 4)
self.assertEqual(t.primitive, PrimitiveType.C_FLOAT)
self.assertEqual(t.kind, TypeKind.FLOAT)
self.assertEqual(t.name, "float")
self.assertEqual(t.size, 4)
self.assertTrue(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(t, self.prog.float_type("float", 4))
self.assertNotEqual(t, self.prog.float_type("double", 4))
self.assertNotEqual(t, self.prog.float_type("float", 8))
2020-07-16 00:34:56 +01:00
self.assertEqual(repr(t), "prog.float_type(name='float', size=4)")
self.assertEqual(sizeof(t), 4)
2020-07-16 00:34:56 +01:00
self.assertRaises(TypeError, self.prog.float_type, None, 4)
def test_complex(self):
2020-07-16 00:34:56 +01:00
t = self.prog.complex_type(
"double _Complex", 16, self.prog.float_type("double", 8)
)
self.assertEqual(t.kind, TypeKind.COMPLEX)
self.assertIsNone(t.primitive)
self.assertEqual(t.language, DEFAULT_LANGUAGE)
self.assertEqual(t.name, "double _Complex")
self.assertEqual(t.size, 16)
2020-07-16 00:34:56 +01:00
self.assertEqual(t.type, self.prog.float_type("double", 8))
self.assertTrue(t.is_complete())
self.assertEqual(
2020-07-16 00:34:56 +01:00
t,
self.prog.complex_type(
"double _Complex", 16, self.prog.float_type("double", 8)
),
)
self.assertNotEqual(
2020-07-16 00:34:56 +01:00
t,
self.prog.complex_type(
"float _Complex", 16, self.prog.float_type("double", 8)
),
)
self.assertNotEqual(
2020-07-16 00:34:56 +01:00
t,
self.prog.complex_type(
"double _Complex", 32, self.prog.float_type("double", 8)
),
)
self.assertNotEqual(
2020-07-16 00:34:56 +01:00
t,
self.prog.complex_type(
"double _Complex", 16, self.prog.float_type("float", 4)
),
)
self.assertEqual(
repr(t),
2020-07-16 00:34:56 +01:00
"prog.complex_type(name='double _Complex', size=16, type=prog.float_type(name='double', size=8))",
)
self.assertEqual(sizeof(t), 16)
2020-07-16 00:34:56 +01:00
self.assertRaises(
TypeError,
self.prog.complex_type,
None,
16,
self.prog.float_type("double", 8),
)
self.assertRaises(
TypeError, self.prog.complex_type, "double _Complex", 16, None
)
self.assertRaisesRegex(
ValueError,
"must be floating-point or integer type",
2020-07-16 00:34:56 +01:00
self.prog.complex_type,
"double _Complex",
16,
2020-07-16 00:34:56 +01:00
self.prog.void_type(),
)
self.assertRaisesRegex(
ValueError,
"must be unqualified",
2020-07-16 00:34:56 +01:00
self.prog.complex_type,
"double _Complex",
16,
2020-07-16 00:34:56 +01:00
self.prog.float_type("double", 8, qualifiers=Qualifiers.CONST),
)
def test_struct(self):
2020-07-16 00:34:56 +01:00
t = self.prog.struct_type(
"point",
8,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32),
),
)
self.assertEqual(t.kind, TypeKind.STRUCT)
self.assertIsNone(t.primitive)
self.assertEqual(t.language, DEFAULT_LANGUAGE)
self.assertEqual(t.tag, "point")
self.assertEqual(t.size, 8)
self.assertEqual(
t.members,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0, 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32, 0),
),
)
self.assertTrue(t.is_complete())
self.assertEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.struct_type(
"point",
8,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32),
),
),
)
# Different tag.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.struct_type(
"pt",
8,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32),
),
),
)
# Different size.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.struct_type(
"point",
16,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32),
),
),
)
# One is anonymous.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.struct_type(
None,
8,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32),
),
),
)
# Different members.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.struct_type(
"point",
8,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("long", 8, True), "x", 0),
TypeMember(self.prog.int_type("long", 8, True), "y", 64),
),
),
)
# Different number of members.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.struct_type(
"point",
8,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32),
TypeMember(self.prog.int_type("int", 4, True), "z", 64),
),
),
)
# One member is anonymous.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.struct_type(
"point",
8,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0),
TypeMember(self.prog.int_type("int", 4, True), None, 32),
),
),
)
# One is incomplete.
2020-07-16 00:34:56 +01:00
self.assertNotEqual(t, self.prog.struct_type("point"))
# Anonymous members with different types.
self.assertNotEqual(
self.prog.struct_type(
"foo",
4,
(TypeMember(self.prog.int_type("int", 4, True), None, 0),),
),
self.prog.struct_type(
"foo",
4,
(TypeMember(self.prog.int_type("unsigned int", 4, False), None, 0),),
),
)
self.assertEqual(
repr(t),
2020-07-16 00:34:56 +01:00
"prog.struct_type(tag='point', size=8, members=(TypeMember(type=prog.int_type(name='int', size=4, is_signed=True), name='x', bit_offset=0), TypeMember(type=prog.int_type(name='int', size=4, is_signed=True), name='y', bit_offset=32)))",
)
self.assertEqual(sizeof(t), 8)
2020-07-16 00:34:56 +01:00
t = self.prog.struct_type(
None,
8,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32),
),
)
self.assertEqual(t.kind, TypeKind.STRUCT)
self.assertIsNone(t.primitive)
self.assertIsNone(t.tag)
self.assertEqual(t.size, 8)
self.assertEqual(
t.members,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0, 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32, 0),
),
)
self.assertTrue(t.is_complete())
2020-07-16 00:34:56 +01:00
t = self.prog.struct_type("color", 0, ())
self.assertEqual(t.kind, TypeKind.STRUCT)
self.assertIsNone(t.primitive)
self.assertEqual(t.tag, "color")
self.assertEqual(t.size, 0)
self.assertEqual(t.members, ())
self.assertTrue(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(repr(t), "prog.struct_type(tag='color', size=0, members=())")
2020-07-16 00:34:56 +01:00
t = self.prog.struct_type("color")
self.assertEqual(t.kind, TypeKind.STRUCT)
self.assertIsNone(t.primitive)
self.assertEqual(t.tag, "color")
self.assertIsNone(t.size)
self.assertIsNone(t.members)
self.assertFalse(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(
repr(t), "prog.struct_type(tag='color', size=None, members=None)"
)
2020-07-16 00:34:56 +01:00
t = self.prog.struct_type(None, None, None)
self.assertEqual(t.kind, TypeKind.STRUCT)
self.assertIsNone(t.primitive)
self.assertEqual(t.tag, None)
self.assertIsNone(t.size)
self.assertIsNone(t.members)
self.assertFalse(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(repr(t), "prog.struct_type(tag=None, size=None, members=None)")
2020-07-16 00:34:56 +01:00
self.assertRaises(TypeError, self.prog.struct_type, 4)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
ValueError, "must not have size", self.prog.struct_type, "point", 8, None
)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
ValueError, "must have size", self.prog.struct_type, "point", None, ()
)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
TypeError, "must be sequence or None", self.prog.struct_type, "point", 8, 4
)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
TypeError, "must be TypeMember", self.prog.struct_type, "point", 8, (4,)
)
# Bit size.
2020-07-16 00:34:56 +01:00
t = self.prog.struct_type(
"point",
8,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0, 4),
TypeMember(self.prog.int_type("int", 4, True), "y", 32, 4),
),
)
self.assertEqual(
t.members,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0, 4),
TypeMember(self.prog.int_type("int", 4, True), "y", 32, 4),
),
)
def test_union(self):
2020-07-16 00:34:56 +01:00
t = self.prog.union_type(
"option",
4,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x"),
TypeMember(self.prog.int_type("unsigned int", 4, False), "y"),
),
)
self.assertEqual(t.kind, TypeKind.UNION)
self.assertIsNone(t.primitive)
self.assertEqual(t.language, DEFAULT_LANGUAGE)
self.assertEqual(t.tag, "option")
self.assertEqual(t.size, 4)
self.assertEqual(
t.members,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0, 0),
TypeMember(self.prog.int_type("unsigned int", 4, False), "y", 0, 0),
),
)
self.assertTrue(t.is_complete())
self.assertEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.union_type(
"option",
4,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x"),
TypeMember(self.prog.int_type("unsigned int", 4, False), "y"),
),
),
)
# Different tag.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.union_type(
"pt",
4,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x"),
TypeMember(self.prog.int_type("unsigned int", 4, False), "y"),
),
),
)
# Different size.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.union_type(
"option",
8,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x"),
TypeMember(self.prog.int_type("unsigned int", 4, False), "y"),
),
),
)
# One is anonymous.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.union_type(
None,
4,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x"),
TypeMember(self.prog.int_type("unsigned int", 4, False), "y"),
),
),
)
# Different members.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.union_type(
"option",
4,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("long", 8, True), "x"),
TypeMember(self.prog.int_type("unsigned long", 8, False), "y"),
),
),
)
# Different number of members.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.union_type(
"option",
4,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x"),
TypeMember(self.prog.int_type("unsigned int", 4, False), "y"),
TypeMember(self.prog.float_type("float", 4), "z"),
),
),
)
# One member is anonymous.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.union_type(
"option",
4,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x"),
TypeMember(self.prog.int_type("unsigned int", 4, False)),
),
),
)
# One is incomplete.
2020-07-16 00:34:56 +01:00
self.assertNotEqual(t, self.prog.union_type("option"))
self.assertEqual(
repr(t),
2020-07-16 00:34:56 +01:00
"prog.union_type(tag='option', size=4, members=(TypeMember(type=prog.int_type(name='int', size=4, is_signed=True), name='x', bit_offset=0), TypeMember(type=prog.int_type(name='unsigned int', size=4, is_signed=False), name='y', bit_offset=0)))",
)
self.assertEqual(sizeof(t), 4)
2020-07-16 00:34:56 +01:00
t = self.prog.union_type(
None,
4,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x"),
TypeMember(self.prog.int_type("unsigned int", 4, False), "y"),
),
)
self.assertEqual(t.kind, TypeKind.UNION)
self.assertIsNone(t.primitive)
self.assertIsNone(t.tag)
self.assertEqual(t.size, 4)
self.assertEqual(
t.members,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0, 0),
TypeMember(self.prog.int_type("unsigned int", 4, False), "y", 0, 0),
),
)
self.assertTrue(t.is_complete())
2020-07-16 00:34:56 +01:00
t = self.prog.union_type("color", 0, ())
self.assertEqual(t.kind, TypeKind.UNION)
self.assertIsNone(t.primitive)
self.assertEqual(t.tag, "color")
self.assertEqual(t.size, 0)
self.assertEqual(t.members, ())
self.assertTrue(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(repr(t), "prog.union_type(tag='color', size=0, members=())")
2020-07-16 00:34:56 +01:00
t = self.prog.union_type("color")
self.assertEqual(t.kind, TypeKind.UNION)
self.assertIsNone(t.primitive)
self.assertEqual(t.tag, "color")
self.assertIsNone(t.size)
self.assertIsNone(t.members)
self.assertFalse(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(
repr(t), "prog.union_type(tag='color', size=None, members=None)"
)
2020-07-16 00:34:56 +01:00
t = self.prog.union_type(None, None, None)
self.assertEqual(t.kind, TypeKind.UNION)
self.assertIsNone(t.primitive)
self.assertEqual(t.tag, None)
self.assertIsNone(t.size)
self.assertIsNone(t.members)
self.assertFalse(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(repr(t), "prog.union_type(tag=None, size=None, members=None)")
2020-07-16 00:34:56 +01:00
self.assertRaises(TypeError, self.prog.union_type, 4)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
ValueError, "must not have size", self.prog.union_type, "option", 8, None
)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
ValueError, "must have size", self.prog.union_type, "option", None, ()
)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
TypeError, "must be sequence or None", self.prog.union_type, "option", 8, 4
)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
TypeError, "must be TypeMember", self.prog.union_type, "option", 8, (4,)
)
# Bit size.
2020-07-16 00:34:56 +01:00
t = self.prog.union_type(
"option",
4,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0, 4),
TypeMember(self.prog.int_type("unsigned int", 4, False), "y", 0, 4),
),
)
self.assertEqual(
t.members,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0, 4),
TypeMember(self.prog.int_type("unsigned int", 4, False), "y", 0, 4),
),
)
def test_class(self):
2020-07-16 00:34:56 +01:00
t = self.prog.class_type(
"coord",
12,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32),
TypeMember(self.prog.int_type("int", 4, True), "z", 64),
),
)
self.assertEqual(t.kind, TypeKind.CLASS)
self.assertIsNone(t.primitive)
self.assertEqual(t.language, DEFAULT_LANGUAGE)
self.assertEqual(t.tag, "coord")
self.assertEqual(t.size, 12)
self.assertEqual(
t.members,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0, 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32, 0),
TypeMember(self.prog.int_type("int", 4, True), "z", 64, 0),
),
)
self.assertTrue(t.is_complete())
self.assertEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.class_type(
"coord",
12,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32),
TypeMember(self.prog.int_type("int", 4, True), "z", 64),
),
),
)
# Different tag.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.class_type(
"crd",
12,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32),
TypeMember(self.prog.int_type("int", 4, True), "z", 64),
),
),
)
# Different size.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.class_type(
"coord",
16,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32),
TypeMember(self.prog.int_type("int", 4, True), "z", 64),
),
),
)
# One is anonymous.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.class_type(
None,
12,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32),
TypeMember(self.prog.int_type("int", 4, True), "z", 64),
),
),
)
# Different members.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.class_type(
"coord",
12,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("long", 8, True), "x", 0),
TypeMember(self.prog.int_type("long", 8, True), "y", 64),
TypeMember(self.prog.int_type("long", 8, True), "z", 128),
),
),
)
# Different number of members.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.class_type(
"coord",
12,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32),
),
),
)
# One member is anonymous.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.class_type(
"coord",
8,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0, 0),
TypeMember(self.prog.int_type("int", 4, True), None, 32, 0),
TypeMember(self.prog.int_type("int", 4, True), "z", 64, 0),
),
),
)
# One is incomplete.
2020-07-16 00:34:56 +01:00
self.assertNotEqual(t, self.prog.class_type("coord"))
self.assertEqual(
repr(t),
2020-07-16 00:34:56 +01:00
"prog.class_type(tag='coord', size=12, members=(TypeMember(type=prog.int_type(name='int', size=4, is_signed=True), name='x', bit_offset=0), TypeMember(type=prog.int_type(name='int', size=4, is_signed=True), name='y', bit_offset=32), TypeMember(type=prog.int_type(name='int', size=4, is_signed=True), name='z', bit_offset=64)))",
)
self.assertEqual(sizeof(t), 12)
2020-07-16 00:34:56 +01:00
t = self.prog.class_type(
None,
12,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32),
TypeMember(self.prog.int_type("int", 4, True), "z", 64),
),
)
self.assertEqual(t.kind, TypeKind.CLASS)
self.assertIsNone(t.primitive)
self.assertIsNone(t.tag)
self.assertEqual(t.size, 12)
self.assertEqual(
t.members,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0, 0),
TypeMember(self.prog.int_type("int", 4, True), "y", 32, 0),
TypeMember(self.prog.int_type("int", 4, True), "z", 64, 0),
),
)
self.assertTrue(t.is_complete())
2020-07-16 00:34:56 +01:00
t = self.prog.class_type("color", 0, ())
self.assertEqual(t.kind, TypeKind.CLASS)
self.assertIsNone(t.primitive)
self.assertEqual(t.tag, "color")
self.assertEqual(t.size, 0)
self.assertEqual(t.members, ())
self.assertTrue(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(repr(t), "prog.class_type(tag='color', size=0, members=())")
2020-07-16 00:34:56 +01:00
t = self.prog.class_type("color")
self.assertEqual(t.kind, TypeKind.CLASS)
self.assertIsNone(t.primitive)
self.assertEqual(t.tag, "color")
self.assertIsNone(t.size)
self.assertIsNone(t.members)
self.assertFalse(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(
repr(t), "prog.class_type(tag='color', size=None, members=None)"
)
2020-07-16 00:34:56 +01:00
t = self.prog.class_type(None, None, None)
self.assertEqual(t.kind, TypeKind.CLASS)
self.assertIsNone(t.primitive)
self.assertEqual(t.tag, None)
self.assertIsNone(t.size)
self.assertIsNone(t.members)
self.assertFalse(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(repr(t), "prog.class_type(tag=None, size=None, members=None)")
2020-07-16 00:34:56 +01:00
self.assertRaises(TypeError, self.prog.class_type, 4)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
ValueError, "must not have size", self.prog.class_type, "coord", 12, None
)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
ValueError, "must have size", self.prog.class_type, "coord", None, ()
)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
TypeError, "must be sequence or None", self.prog.class_type, "coord", 12, 4
)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
TypeError, "must be TypeMember", self.prog.class_type, "coord", 12, (4,)
)
# Bit size.
2020-07-16 00:34:56 +01:00
t = self.prog.class_type(
"coord",
12,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0, 4),
TypeMember(self.prog.int_type("int", 4, True), "y", 32, 4),
TypeMember(self.prog.int_type("int", 4, True), "z", 64, 4),
),
)
self.assertEqual(
t.members,
(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True), "x", 0, 4),
TypeMember(self.prog.int_type("int", 4, True), "y", 32, 4),
TypeMember(self.prog.int_type("int", 4, True), "z", 64, 4),
),
)
def test_enum(self):
2020-07-16 00:34:56 +01:00
t = self.prog.enum_type(
"color",
2020-07-16 00:34:56 +01:00
self.prog.int_type("unsigned int", 4, False),
(
TypeEnumerator("RED", 0),
TypeEnumerator("GREEN", 1),
TypeEnumerator("BLUE", 2),
),
)
self.assertEqual(t.kind, TypeKind.ENUM)
self.assertIsNone(t.primitive)
self.assertEqual(t.language, DEFAULT_LANGUAGE)
self.assertEqual(t.tag, "color")
2020-07-16 00:34:56 +01:00
self.assertEqual(t.type, self.prog.int_type("unsigned int", 4, False))
self.assertEqual(
t.enumerators,
(
TypeEnumerator("RED", 0),
TypeEnumerator("GREEN", 1),
TypeEnumerator("BLUE", 2),
),
)
self.assertTrue(t.is_complete())
self.assertEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.enum_type(
"color",
2020-07-16 00:34:56 +01:00
self.prog.int_type("unsigned int", 4, False),
(
TypeEnumerator("RED", 0),
TypeEnumerator("GREEN", 1),
TypeEnumerator("BLUE", 2),
),
),
)
# Different tag.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.enum_type(
"COLOR",
2020-07-16 00:34:56 +01:00
self.prog.int_type("unsigned int", 4, False),
(
TypeEnumerator("RED", 0),
TypeEnumerator("GREEN", 1),
TypeEnumerator("BLUE", 2),
),
),
)
# One is anonymous.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.enum_type(
None,
2020-07-16 00:34:56 +01:00
self.prog.int_type("unsigned int", 4, False),
(
TypeEnumerator("RED", 0),
TypeEnumerator("GREEN", 1),
TypeEnumerator("BLUE", 2),
),
),
)
# Different compatible type.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.enum_type(
"color",
2020-07-16 00:34:56 +01:00
self.prog.int_type("int", 4, True),
(
TypeEnumerator("RED", 0),
TypeEnumerator("GREEN", 1),
TypeEnumerator("BLUE", 2),
),
),
)
# Different enumerators.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.enum_type(
"color",
2020-07-16 00:34:56 +01:00
self.prog.int_type("unsigned int", 4, False),
(
TypeEnumerator("RED", 0),
TypeEnumerator("YELLOW", 1),
TypeEnumerator("BLUE", 2),
),
),
)
# Different number of enumerators.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.enum_type(
"color",
2020-07-16 00:34:56 +01:00
self.prog.int_type("unsigned int", 4, False),
(TypeEnumerator("RED", 0), TypeEnumerator("GREEN", 1)),
),
)
# One is incomplete.
2020-07-16 00:34:56 +01:00
self.assertNotEqual(t, self.prog.enum_type("color"))
self.assertEqual(
repr(t),
2020-07-16 00:34:56 +01:00
"prog.enum_type(tag='color', type=prog.int_type(name='unsigned int', size=4, is_signed=False), enumerators=(TypeEnumerator('RED', 0), TypeEnumerator('GREEN', 1), TypeEnumerator('BLUE', 2)))",
)
self.assertEqual(sizeof(t), 4)
2020-07-16 00:34:56 +01:00
t = self.prog.enum_type("color", None, None)
self.assertEqual(t.kind, TypeKind.ENUM)
self.assertIsNone(t.primitive)
self.assertEqual(t.tag, "color")
self.assertIsNone(t.type)
self.assertIsNone(t.enumerators)
self.assertFalse(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(
repr(t), "prog.enum_type(tag='color', type=None, enumerators=None)"
)
# A type with no enumerators isn't valid in C, but we allow it.
2020-07-16 00:34:56 +01:00
t = self.prog.enum_type(
"color", self.prog.int_type("unsigned int", 4, False), ()
)
self.assertEqual(t.kind, TypeKind.ENUM)
self.assertIsNone(t.primitive)
self.assertEqual(t.tag, "color")
2020-07-16 00:34:56 +01:00
self.assertEqual(t.type, self.prog.int_type("unsigned int", 4, False))
self.assertEqual(t.enumerators, ())
self.assertTrue(t.is_complete())
self.assertEqual(
repr(t),
2020-07-16 00:34:56 +01:00
"prog.enum_type(tag='color', type=prog.int_type(name='unsigned int', size=4, is_signed=False), enumerators=())",
)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
TypeError, "must be Type", self.prog.enum_type, "color", 4, ()
)
self.assertRaisesRegex(
ValueError,
"must be integer type",
self.prog.enum_type,
"color",
self.prog.void_type(),
(),
)
self.assertRaisesRegex(
ValueError,
"must be unqualified",
2020-07-16 00:34:56 +01:00
self.prog.enum_type,
"color",
2020-07-16 00:34:56 +01:00
self.prog.int_type("unsigned int", 4, True, qualifiers=Qualifiers.CONST),
(),
)
self.assertRaisesRegex(
ValueError,
"must not have compatible type",
2020-07-16 00:34:56 +01:00
self.prog.enum_type,
"color",
2020-07-16 00:34:56 +01:00
self.prog.int_type("unsigned int", 4, False),
None,
)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
ValueError,
"must have compatible type",
self.prog.enum_type,
"color",
None,
(),
)
self.assertRaisesRegex(
TypeError,
"must be sequence or None",
2020-07-16 00:34:56 +01:00
self.prog.enum_type,
"color",
2020-07-16 00:34:56 +01:00
self.prog.int_type("unsigned int", 4, False),
4,
)
self.assertRaisesRegex(
TypeError,
"must be TypeEnumerator",
2020-07-16 00:34:56 +01:00
self.prog.enum_type,
"color",
2020-07-16 00:34:56 +01:00
self.prog.int_type("unsigned int", 4, False),
(4,),
)
def test_typedef(self):
2020-07-16 00:34:56 +01:00
t = self.prog.typedef_type("INT", self.prog.int_type("int", 4, True))
self.assertEqual(t.kind, TypeKind.TYPEDEF)
self.assertIsNone(t.primitive)
self.assertEqual(t.language, DEFAULT_LANGUAGE)
self.assertEqual(t.name, "INT")
2020-07-16 00:34:56 +01:00
self.assertEqual(t.type, self.prog.int_type("int", 4, True))
self.assertTrue(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(
t, self.prog.typedef_type("INT", self.prog.int_type("int", 4, True))
)
# Different name.
2020-07-16 00:34:56 +01:00
self.assertNotEqual(
t, self.prog.typedef_type("integer", self.prog.int_type("int", 4, True))
)
# Different type.
self.assertNotEqual(
2020-07-16 00:34:56 +01:00
t,
self.prog.typedef_type(
"integer", self.prog.int_type("unsigned int", 4, False)
),
)
self.assertNotEqual(
2020-07-16 00:34:56 +01:00
t,
self.prog.typedef_type(
"INT", self.prog.int_type("int", 4, True, qualifiers=Qualifiers.CONST)
),
)
self.assertEqual(
repr(t),
2020-07-16 00:34:56 +01:00
"prog.typedef_type(name='INT', type=prog.int_type(name='int', size=4, is_signed=True))",
)
self.assertEqual(sizeof(t), 4)
2020-07-16 00:34:56 +01:00
t = self.prog.typedef_type("VOID", self.prog.void_type())
self.assertFalse(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertRaises(
TypeError, self.prog.typedef_type, None, self.prog.int_type("int", 4, True)
)
self.assertRaises(TypeError, self.prog.typedef_type, "INT", 4)
self.assertEqual(
2020-07-16 00:34:56 +01:00
self.prog.typedef_type(
"size_t", self.prog.int_type("unsigned long", 8, False)
).primitive,
PrimitiveType.C_SIZE_T,
)
self.assertEqual(
2020-07-16 00:34:56 +01:00
self.prog.typedef_type(
"ptrdiff_t", self.prog.int_type("long", 8, True)
).primitive,
PrimitiveType.C_PTRDIFF_T,
)
def test_pointer(self):
2020-07-16 00:34:56 +01:00
t = self.prog.pointer_type(self.prog.int_type("int", 4, True), 8)
self.assertEqual(t.kind, TypeKind.POINTER)
self.assertIsNone(t.primitive)
self.assertEqual(t.language, DEFAULT_LANGUAGE)
self.assertEqual(t.size, 8)
2020-07-16 00:34:56 +01:00
self.assertEqual(t.type, self.prog.int_type("int", 4, True))
self.assertTrue(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(
t, self.prog.pointer_type(self.prog.int_type("int", 4, True), 8)
)
# Default size.
self.assertEqual(t, self.prog.pointer_type(self.prog.int_type("int", 4, True)))
self.assertEqual(
t, self.prog.pointer_type(self.prog.int_type("int", 4, True), None)
)
# Different size.
2020-07-16 00:34:56 +01:00
self.assertNotEqual(
t, self.prog.pointer_type(self.prog.int_type("int", 4, True), 4)
)
# Different type.
2020-07-16 00:34:56 +01:00
self.assertNotEqual(t, self.prog.pointer_type(self.prog.void_type(), 8))
self.assertNotEqual(
t,
self.prog.pointer_type(self.prog.void_type(qualifiers=Qualifiers.CONST), 8),
)
self.assertEqual(
repr(t),
2020-07-16 00:34:56 +01:00
"prog.pointer_type(type=prog.int_type(name='int', size=4, is_signed=True))",
)
2020-07-16 00:34:56 +01:00
self.assertEqual(
repr(self.prog.pointer_type(self.prog.int_type("int", 4, True), 4)),
"prog.pointer_type(type=prog.int_type(name='int', size=4, is_signed=True), size=4)",
)
self.assertEqual(sizeof(t), 8)
2020-07-16 00:34:56 +01:00
self.assertRaises(TypeError, self.prog.pointer_type, 4)
def test_array(self):
2020-07-16 00:34:56 +01:00
t = self.prog.array_type(self.prog.int_type("int", 4, True), 10)
self.assertEqual(t.kind, TypeKind.ARRAY)
self.assertIsNone(t.primitive)
self.assertEqual(t.language, DEFAULT_LANGUAGE)
self.assertEqual(t.length, 10)
2020-07-16 00:34:56 +01:00
self.assertEqual(t.type, self.prog.int_type("int", 4, True))
self.assertTrue(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertEqual(
t, self.prog.array_type(self.prog.int_type("int", 4, True), 10)
)
# Different length.
2020-07-16 00:34:56 +01:00
self.assertNotEqual(
t, self.prog.array_type(self.prog.int_type("int", 4, True), 4)
)
# Different type.
2020-07-16 00:34:56 +01:00
self.assertNotEqual(t, self.prog.array_type(self.prog.void_type(), 10))
self.assertNotEqual(
t,
self.prog.array_type(self.prog.void_type(qualifiers=Qualifiers.CONST), 10),
)
self.assertEqual(
repr(t),
2020-07-16 00:34:56 +01:00
"prog.array_type(type=prog.int_type(name='int', size=4, is_signed=True), length=10)",
)
self.assertEqual(sizeof(t), 40)
2020-07-16 00:34:56 +01:00
t = self.prog.array_type(self.prog.int_type("int", 4, True), 0)
self.assertEqual(t.kind, TypeKind.ARRAY)
self.assertIsNone(t.primitive)
self.assertEqual(t.length, 0)
2020-07-16 00:34:56 +01:00
self.assertEqual(t.type, self.prog.int_type("int", 4, True))
self.assertTrue(t.is_complete())
2020-07-16 00:34:56 +01:00
t = self.prog.array_type(self.prog.int_type("int", 4, True))
self.assertEqual(t.kind, TypeKind.ARRAY)
self.assertIsNone(t.primitive)
self.assertIsNone(t.length)
2020-07-16 00:34:56 +01:00
self.assertEqual(t.type, self.prog.int_type("int", 4, True))
self.assertFalse(t.is_complete())
2020-07-16 00:34:56 +01:00
self.assertRaises(TypeError, self.prog.array_type, 10, 4)
def test_function(self):
2020-07-16 00:34:56 +01:00
t = self.prog.function_type(
self.prog.void_type(),
(TypeParameter(self.prog.int_type("int", 4, True), "n"),),
)
self.assertEqual(t.kind, TypeKind.FUNCTION)
self.assertIsNone(t.primitive)
self.assertEqual(t.language, DEFAULT_LANGUAGE)
2020-07-16 00:34:56 +01:00
self.assertEqual(t.type, self.prog.void_type())
self.assertEqual(
t.parameters, (TypeParameter(self.prog.int_type("int", 4, True), "n"),)
)
self.assertFalse(t.is_variadic)
self.assertTrue(t.is_complete())
self.assertEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.function_type(
self.prog.void_type(),
(TypeParameter(self.prog.int_type("int", 4, True), "n"),),
),
)
# Different return type.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.function_type(
self.prog.int_type("int", 4, True),
(TypeParameter(self.prog.int_type("int", 4, True), "n"),),
),
)
# Different parameter name.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.function_type(
self.prog.void_type(),
(TypeParameter(self.prog.int_type("int", 4, True), "x"),),
),
)
# Unnamed parameter.
self.assertNotEqual(
2020-07-16 00:34:56 +01:00
t,
self.prog.function_type(
self.prog.void_type(),
(TypeParameter(self.prog.int_type("int", 4, True)),),
2020-07-16 00:34:56 +01:00
),
)
# Different number of parameters.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.function_type(
self.prog.void_type(),
(
2020-07-16 00:34:56 +01:00
TypeParameter(self.prog.int_type("int", 4, True), "n"),
TypeParameter(
self.prog.pointer_type(self.prog.void_type(), 8), "p"
),
),
),
)
# One is variadic.
self.assertNotEqual(
t,
2020-07-16 00:34:56 +01:00
self.prog.function_type(
self.prog.void_type(),
(TypeParameter(self.prog.int_type("int", 4, True), "n"),),
True,
),
)
self.assertEqual(
repr(t),
2020-07-16 00:34:56 +01:00
"prog.function_type(type=prog.void_type(), parameters=(TypeParameter(type=prog.int_type(name='int', size=4, is_signed=True), name='n'),), is_variadic=False)",
)
self.assertRaises(TypeError, sizeof, t)
2020-07-16 00:34:56 +01:00
self.assertFalse(
self.prog.function_type(self.prog.void_type(), (), False).is_variadic
)
self.assertTrue(
self.prog.function_type(self.prog.void_type(), (), True).is_variadic
)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
TypeError, "must be _drgn\.Type", self.prog.function_type, None, ()
)
self.assertRaisesRegex(
2020-07-16 00:34:56 +01:00
TypeError,
"must be sequence",
self.prog.function_type,
self.prog.void_type(),
None,
)
self.assertRaisesRegex(
TypeError,
"must be TypeParameter",
self.prog.function_type,
self.prog.void_type(),
(4,),
)
def test_cycle(self):
2020-07-16 00:34:56 +01:00
t1 = self.prog.struct_type(
"foo", 8, (TypeMember(lambda: self.prog.pointer_type(t1), "next"),)
)
t2 = self.prog.struct_type(
"foo", 8, (TypeMember(lambda: self.prog.pointer_type(t2), "next"),)
)
t3, t4 = (
2020-07-16 00:34:56 +01:00
self.prog.struct_type(
"foo", 8, (TypeMember(lambda: self.prog.pointer_type(t4), "next"),)
),
self.prog.struct_type(
"foo", 8, (TypeMember(lambda: self.prog.pointer_type(t3), "next"),)
),
)
self.assertEqual(t1, t2)
self.assertEqual(t2, t3)
self.assertEqual(t3, t4)
self.assertEqual(
repr(t1),
2020-07-16 00:34:56 +01:00
"prog.struct_type(tag='foo', size=8, members=(TypeMember(type=prog.pointer_type(type=prog.struct_type(tag='foo', ...)), name='next', bit_offset=0),))",
)
def test_cycle2(self):
2020-07-16 00:34:56 +01:00
t1 = self.prog.struct_type(
"list_head",
16,
(
2020-07-16 00:34:56 +01:00
TypeMember(lambda: self.prog.pointer_type(t1), "next"),
TypeMember(lambda: self.prog.pointer_type(t1), "prev", 8),
),
)
2020-07-16 00:34:56 +01:00
t2 = self.prog.struct_type(
"list_head",
16,
(
2020-07-16 00:34:56 +01:00
TypeMember(lambda: self.prog.pointer_type(t2), "next"),
TypeMember(lambda: self.prog.pointer_type(t2), "prev", 8),
),
)
self.assertEqual(t1, t2)
self.assertEqual(
repr(t1),
2020-07-16 00:34:56 +01:00
"prog.struct_type(tag='list_head', size=16, members=(TypeMember(type=prog.pointer_type(type=prog.struct_type(tag='list_head', ...)), name='next', bit_offset=0), TypeMember(type=prog.pointer_type(type=prog.struct_type(tag='list_head', ...)), name='prev', bit_offset=8)))",
)
def test_infinite(self):
2020-07-16 00:34:56 +01:00
f = lambda: self.prog.struct_type("foo", 0, (TypeMember(f, "next"),))
self.assertEqual(
repr(f()),
2020-07-16 00:34:56 +01:00
"prog.struct_type(tag='foo', size=0, members=(TypeMember(type=prog.struct_type(tag='foo', ...), name='next', bit_offset=0),))",
)
with self.assertRaisesRegex(RecursionError, "maximum.*depth"):
f() == f()
def test_bad_thunk(self):
2020-07-16 00:34:56 +01:00
t1 = self.prog.struct_type(
"foo", 16, (TypeMember(lambda: exec('raise Exception("test")'), "bar"),)
)
with self.assertRaisesRegex(Exception, "test"):
t1.members[0].type
2020-07-16 00:34:56 +01:00
t1 = self.prog.struct_type("foo", 16, (TypeMember(lambda: 0, "bar"),))
with self.assertRaisesRegex(TypeError, "type callable must return Type"):
t1.members[0].type
def test_qualifiers(self):
2020-07-16 00:34:56 +01:00
self.assertEqual(self.prog.void_type().qualifiers, Qualifiers(0))
2020-07-16 00:34:56 +01:00
t = self.prog.void_type(qualifiers=Qualifiers.CONST | Qualifiers.VOLATILE)
self.assertEqual(t.qualifiers, Qualifiers.CONST | Qualifiers.VOLATILE)
self.assertEqual(
2020-07-16 00:34:56 +01:00
repr(t), "prog.void_type(qualifiers=<Qualifiers.VOLATILE|CONST: 3>)"
)
2020-07-16 00:34:56 +01:00
self.assertEqual(
t.qualified(Qualifiers.ATOMIC),
self.prog.void_type(qualifiers=Qualifiers.ATOMIC),
)
self.assertEqual(t.unqualified(), self.prog.void_type())
self.assertEqual(t.qualified(Qualifiers(0)), t.unqualified())
2020-07-16 00:34:56 +01:00
self.assertRaisesRegex(
TypeError, "expected Qualifiers", self.prog.void_type, qualifiers=1.5
2020-07-16 00:34:56 +01:00
)
def test_language(self):
2020-07-16 00:34:56 +01:00
self.assertEqual(self.prog.void_type(language=None).language, DEFAULT_LANGUAGE)
self.assertEqual(self.prog.void_type(language=Language.C).language, Language.C)
2020-03-03 00:01:38 +00:00
self.assertEqual(
2020-07-16 00:34:56 +01:00
self.prog.int_type("int", 4, True, language=Language.CPP).language,
Language.CPP,
2020-03-03 00:01:38 +00:00
)
self.assertNotEqual(
2020-07-16 00:34:56 +01:00
self.prog.int_type("int", 4, True, language=Language.C),
self.prog.int_type("int", 4, True, language=Language.CPP),
)
def test_language_repr(self):
self.assertEqual(
repr(self.prog.void_type(language=Language.CPP)),
"prog.void_type(language=Language.CPP)",
)
def test_cmp(self):
2020-07-16 00:34:56 +01:00
self.assertEqual(self.prog.void_type(), self.prog.void_type())
self.assertEqual(
self.prog.void_type(qualifiers=Qualifiers.CONST),
self.prog.void_type(qualifiers=Qualifiers.CONST),
)
self.assertNotEqual(
self.prog.void_type(), self.prog.void_type(qualifiers=Qualifiers.CONST)
)
self.assertNotEqual(self.prog.void_type(), self.prog.int_type("int", 4, True))
self.assertNotEqual(self.prog.void_type(), 1)
self.assertNotEqual(1, self.prog.void_type())
def test_different_programs_compare(self):
self.assertRaisesRegex(
ValueError,
"types are from different programs",
operator.eq,
self.prog.void_type(),
Program().void_type(),
)
def test_different_programs_complex(self):
self.assertRaisesRegex(
ValueError,
"type is from different program",
self.prog.complex_type,
"double _Complex",
16,
Program().float_type("double", 8),
)
def test_different_programs_compound(self):
self.assertRaisesRegex(
ValueError,
"type is from different program",
self.prog.struct_type,
None,
4,
(TypeMember(Program().int_type("int", 4, True)),),
)
def test_different_programs_compound_callback(self):
with self.assertRaisesRegex(ValueError, "type is from different program"):
self.prog.struct_type(
None, 4, (TypeMember(lambda: Program().int_type("int", 4, True)),)
).members[0].type
def test_different_programs_enum(self):
self.assertRaisesRegex(
ValueError,
"type is from different program",
self.prog.enum_type,
None,
Program().int_type("int", 4, True),
(),
)
def test_different_programs_typedef(self):
self.assertRaisesRegex(
ValueError,
"type is from different program",
self.prog.typedef_type,
"INT",
Program().int_type("int", 4, True),
)
2020-07-16 00:34:56 +01:00
def test_different_programs_pointer(self):
self.assertRaisesRegex(
ValueError,
"type is from different program",
self.prog.pointer_type,
Program().int_type("int", 4, True),
)
2020-07-16 00:34:56 +01:00
def test_different_programs_array(self):
self.assertRaisesRegex(
ValueError,
"type is from different program",
self.prog.pointer_type,
Program().int_type("int", 4, True),
)
def test_different_programs_function_return(self):
self.assertRaisesRegex(
ValueError,
"type is from different program",
self.prog.function_type,
Program().int_type("int", 4, True),
(),
)
def test_different_programs_function_parameter(self):
self.assertRaisesRegex(
ValueError,
"type is from different program",
self.prog.function_type,
self.prog.void_type(),
(TypeParameter(Program().int_type("int", 4, True)),),
)
def test_different_programs_function_parameter_callback(self):
with self.assertRaisesRegex(ValueError, "type is from different program"):
self.prog.function_type(
self.prog.void_type(),
(TypeParameter(lambda: Program().int_type("int", 4, True)),),
).parameters[0].type
class TestTypeEnumerator(MockProgramTestCase):
def test_init(self):
e = TypeEnumerator("a", 1)
self.assertEqual(e.name, "a")
self.assertEqual(e.value, 1)
self.assertRaises(TypeError, TypeEnumerator, "a", None)
self.assertRaises(TypeError, TypeEnumerator, None, 1)
def test_repr(self):
e = TypeEnumerator("a", 1)
self.assertEqual(repr(e), "TypeEnumerator('a', 1)")
def test_sequence(self):
e = TypeEnumerator("a", 1)
name, value = e
self.assertEqual(name, "a")
self.assertEqual(value, 1)
self.assertEqual(list(e), ["a", 1])
def test_cmp(self):
self.assertEqual(TypeEnumerator("a", 1), TypeEnumerator(name="a", value=1))
self.assertNotEqual(TypeEnumerator("a", 1), TypeEnumerator("a", 2))
self.assertNotEqual(TypeEnumerator("b", 1), TypeEnumerator("a", 1))
2020-07-16 00:34:56 +01:00
class TestTypeMember(MockProgramTestCase):
def test_init(self):
2020-07-16 00:34:56 +01:00
m = TypeMember(self.prog.void_type())
self.assertEqual(m.type, self.prog.void_type())
self.assertIsNone(m.name)
self.assertEqual(m.bit_offset, 0)
self.assertEqual(m.offset, 0)
self.assertEqual(m.bit_field_size, 0)
2020-07-16 00:34:56 +01:00
m = TypeMember(self.prog.void_type(), "foo")
self.assertEqual(m.type, self.prog.void_type())
self.assertEqual(m.name, "foo")
self.assertEqual(m.bit_offset, 0)
self.assertEqual(m.offset, 0)
self.assertEqual(m.bit_field_size, 0)
2020-07-16 00:34:56 +01:00
m = TypeMember(self.prog.void_type(), "foo", 8)
self.assertEqual(m.type, self.prog.void_type())
self.assertEqual(m.name, "foo")
self.assertEqual(m.bit_offset, 8)
self.assertEqual(m.offset, 1)
self.assertEqual(m.bit_field_size, 0)
2020-07-16 00:34:56 +01:00
m = TypeMember(self.prog.void_type(), "foo", 9, 7)
self.assertEqual(m.type, self.prog.void_type())
self.assertEqual(m.name, "foo")
self.assertEqual(m.bit_offset, 9)
self.assertRaises(ValueError, getattr, m, "offset")
self.assertEqual(m.bit_field_size, 7)
self.assertRaises(TypeError, TypeMember, None)
2020-07-16 00:34:56 +01:00
self.assertRaises(TypeError, TypeMember, self.prog.void_type(), 1)
self.assertRaises(TypeError, TypeMember, self.prog.void_type(), "foo", None)
self.assertRaises(TypeError, TypeMember, self.prog.void_type(), "foo", 0, None)
def test_callable(self):
2020-07-16 00:34:56 +01:00
m = TypeMember(self.prog.void_type)
self.assertEqual(m.type, self.prog.void_type())
2020-07-16 00:34:56 +01:00
m = TypeMember(lambda: self.prog.int_type("int", 4, True))
self.assertEqual(m.type, self.prog.int_type("int", 4, True))
m = TypeMember(lambda: None)
self.assertRaises(TypeError, getattr, m, "type")
def test_repr(self):
2020-07-16 00:34:56 +01:00
m = TypeMember(type=self.prog.void_type, name="foo")
self.assertEqual(
2020-07-16 00:34:56 +01:00
repr(m), "TypeMember(type=prog.void_type(), name='foo', bit_offset=0)"
)
2020-07-16 00:34:56 +01:00
m = TypeMember(type=self.prog.void_type, bit_field_size=4)
self.assertEqual(
repr(m),
2020-07-16 00:34:56 +01:00
"TypeMember(type=prog.void_type(), name=None, bit_offset=0, bit_field_size=4)",
)
m = TypeMember(lambda: None)
self.assertRaises(TypeError, repr, m)
def test_cmp(self):
self.assertEqual(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.void_type()),
TypeMember(self.prog.void_type(), None, 0, 0),
)
self.assertEqual(
TypeMember(
bit_offset=9, bit_field_size=7, type=self.prog.void_type, name="foo"
),
TypeMember(self.prog.void_type(), "foo", 9, 7),
)
self.assertNotEqual(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.int_type("int", 4, True)),
TypeMember(self.prog.void_type(), None, 0, 0),
)
self.assertNotEqual(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.void_type(), "foo"),
TypeMember(self.prog.void_type(), None, 0, 0),
)
self.assertNotEqual(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.void_type(), bit_offset=8),
TypeMember(self.prog.void_type(), None, 0, 0),
)
self.assertNotEqual(
2020-07-16 00:34:56 +01:00
TypeMember(self.prog.void_type(), bit_field_size=8),
TypeMember(self.prog.void_type(), None, 0, 0),
)
2020-07-16 00:34:56 +01:00
class TestTypeParameter(MockProgramTestCase):
def test_init(self):
2020-07-16 00:34:56 +01:00
p = TypeParameter(self.prog.void_type())
self.assertEqual(p.type, self.prog.void_type())
self.assertIsNone(p.name)
2020-07-16 00:34:56 +01:00
p = TypeParameter(self.prog.void_type(), "foo")
self.assertEqual(p.type, self.prog.void_type())
self.assertEqual(p.name, "foo")
self.assertRaises(TypeError, TypeParameter, None)
2020-07-16 00:34:56 +01:00
self.assertRaises(TypeError, TypeParameter, self.prog.void_type(), 1)
def test_callable(self):
2020-07-16 00:34:56 +01:00
p = TypeParameter(self.prog.void_type)
self.assertEqual(p.type, self.prog.void_type())
2020-07-16 00:34:56 +01:00
p = TypeParameter(lambda: self.prog.int_type("int", 4, True))
self.assertEqual(p.type, self.prog.int_type("int", 4, True))
p = TypeParameter(lambda: None)
self.assertRaises(TypeError, getattr, p, "type")
def test_repr(self):
2020-07-16 00:34:56 +01:00
p = TypeParameter(type=self.prog.void_type, name="foo")
self.assertEqual(repr(p), "TypeParameter(type=prog.void_type(), name='foo')")
2020-07-16 00:34:56 +01:00
p = TypeParameter(type=self.prog.void_type)
self.assertEqual(repr(p), "TypeParameter(type=prog.void_type(), name=None)")
p = TypeParameter(lambda: None)
self.assertRaises(TypeError, repr, p)
def test_cmp(self):
self.assertEqual(
2020-07-16 00:34:56 +01:00
TypeParameter(self.prog.void_type()),
TypeParameter(self.prog.void_type(), None),
)
self.assertEqual(
TypeParameter(name="foo", type=self.prog.void_type),
TypeParameter(self.prog.void_type(), "foo"),
)
self.assertNotEqual(
2020-07-16 00:34:56 +01:00
TypeParameter(self.prog.int_type("int", 4, True)),
TypeParameter(self.prog.void_type(), None),
)
self.assertNotEqual(
2020-07-16 00:34:56 +01:00
TypeParameter(self.prog.void_type(), "foo"),
TypeParameter(self.prog.void_type(), None),
)