Skip to main content

melior/ir/type/
integer.rs

1use super::TypeLike;
2use crate::{ir::Type, Context, Error};
3use mlir_sys::{
4    mlirIntegerTypeGet, mlirIntegerTypeGetWidth, mlirIntegerTypeIsSigned,
5    mlirIntegerTypeIsSignless, mlirIntegerTypeIsUnsigned, mlirIntegerTypeSignedGet,
6    mlirIntegerTypeUnsignedGet, MlirType,
7};
8
9/// A integer type.
10#[derive(Clone, Copy, Debug)]
11pub struct IntegerType<'c> {
12    r#type: Type<'c>,
13}
14
15impl<'c> IntegerType<'c> {
16    /// Creates an integer type.
17    pub fn new(context: &'c Context, bits: u32) -> Self {
18        Self {
19            r#type: unsafe { Type::from_raw(mlirIntegerTypeGet(context.to_raw(), bits)) },
20        }
21    }
22
23    /// Creates a signed integer type.
24    pub fn signed(context: &'c Context, bits: u32) -> Self {
25        unsafe { Self::from_raw(mlirIntegerTypeSignedGet(context.to_raw(), bits)) }
26    }
27
28    /// Creates an unsigned integer type.
29    pub fn unsigned(context: &'c Context, bits: u32) -> Self {
30        unsafe { Self::from_raw(mlirIntegerTypeUnsignedGet(context.to_raw(), bits)) }
31    }
32
33    /// Returns a bit width.
34    pub fn width(&self) -> u32 {
35        unsafe { mlirIntegerTypeGetWidth(self.to_raw()) }
36    }
37
38    /// Checks if an integer type is signed.
39    pub fn is_signed(&self) -> bool {
40        unsafe { mlirIntegerTypeIsSigned(self.to_raw()) }
41    }
42
43    /// Checks if an integer type is signless.
44    pub fn is_signless(&self) -> bool {
45        unsafe { mlirIntegerTypeIsSignless(self.to_raw()) }
46    }
47
48    /// Checks if an integer type is unsigned.
49    pub fn is_unsigned(&self) -> bool {
50        unsafe { mlirIntegerTypeIsUnsigned(self.to_raw()) }
51    }
52}
53
54type_traits!(IntegerType, is_integer, "integer");
55
56#[cfg(test)]
57mod tests {
58    use super::*;
59
60    #[test]
61    fn new() {
62        assert!(IntegerType::new(&Context::new(), 64).is_integer());
63    }
64
65    #[test]
66    fn signed() {
67        assert!(IntegerType::signed(&Context::new(), 64).is_integer());
68    }
69
70    #[test]
71    fn unsigned() {
72        assert!(IntegerType::unsigned(&Context::new(), 64).is_integer());
73    }
74
75    #[test]
76    fn signed_integer() {
77        let context = Context::new();
78
79        assert_eq!(
80            Type::from(IntegerType::signed(&context, 42)),
81            Type::parse(&context, "si42").unwrap()
82        );
83    }
84
85    #[test]
86    fn unsigned_integer() {
87        let context = Context::new();
88
89        assert_eq!(
90            Type::from(IntegerType::unsigned(&context, 42)),
91            Type::parse(&context, "ui42").unwrap()
92        );
93    }
94
95    #[test]
96    fn get_width() {
97        let context = Context::new();
98
99        assert_eq!(IntegerType::new(&context, 64).width(), 64);
100    }
101
102    #[test]
103    fn check_sign() {
104        let context = Context::new();
105        let signless = IntegerType::new(&context, 42);
106        let signed = IntegerType::signed(&context, 42);
107        let unsigned = IntegerType::unsigned(&context, 42);
108
109        assert!(signless.is_signless());
110        assert!(!signed.is_signless());
111        assert!(!unsigned.is_signless());
112
113        assert!(!signless.is_signed());
114        assert!(signed.is_signed());
115        assert!(!unsigned.is_signed());
116
117        assert!(!signless.is_unsigned());
118        assert!(!signed.is_unsigned());
119        assert!(unsigned.is_unsigned());
120    }
121}