melior/dialect/llvm/
type.rs1use crate::{
4 context::Context,
5 ir::{Type, TypeLike},
6};
7use mlir_sys::{
8 mlirLLVMArrayTypeGet, mlirLLVMFunctionTypeGet, mlirLLVMPointerTypeGet,
9 mlirLLVMStructTypeLiteralGet, mlirLLVMVoidTypeGet,
10};
11
12pub fn array(r#type: Type, len: u32) -> Type {
16 unsafe { Type::from_raw(mlirLLVMArrayTypeGet(r#type.to_raw(), len)) }
17}
18
19pub fn function<'c>(
21 result: Type<'c>,
22 arguments: &[Type<'c>],
23 variadic_arguments: bool,
24) -> Type<'c> {
25 unsafe {
26 Type::from_raw(mlirLLVMFunctionTypeGet(
27 result.to_raw(),
28 arguments.len() as isize,
29 arguments as *const _ as *const _,
30 variadic_arguments,
31 ))
32 }
33}
34
35#[deprecated(
37 since = "0.11.0",
38 note = "please use the pointer method, all pointers are opaque in LLVM 19"
39)]
40pub fn opaque_pointer(context: &Context) -> Type {
41 pointer(context, 0)
42}
43
44pub fn pointer(context: &Context, address_space: u32) -> Type {
46 unsafe { Type::from_raw(mlirLLVMPointerTypeGet(context.to_raw(), address_space)) }
47}
48
49pub fn r#struct<'c>(context: &'c Context, fields: &[Type<'c>], packed: bool) -> Type<'c> {
51 unsafe {
52 Type::from_raw(mlirLLVMStructTypeLiteralGet(
53 context.to_raw(),
54 fields.len() as isize,
55 fields as *const _ as *const _,
56 packed,
57 ))
58 }
59}
60
61pub fn void(context: &Context) -> Type {
63 unsafe { Type::from_raw(mlirLLVMVoidTypeGet(context.to_raw())) }
64}
65
66#[cfg(test)]
67mod tests {
68 use super::*;
69 use crate::{dialect, ir::r#type::IntegerType};
70
71 fn create_context() -> Context {
72 let context = Context::new();
73
74 dialect::DialectHandle::llvm().register_dialect(&context);
75 context.get_or_load_dialect("llvm");
76
77 context
78 }
79
80 #[test]
81 fn pointer() {
82 let context = create_context();
83
84 assert_eq!(
85 super::pointer(&context, 0),
86 Type::parse(&context, "!llvm.ptr").unwrap()
87 );
88 }
89
90 #[test]
91 fn pointer_with_address_space() {
92 let context = create_context();
93
94 assert_eq!(
95 super::pointer(&context, 4),
96 Type::parse(&context, "!llvm.ptr<4>").unwrap()
97 );
98 }
99
100 #[test]
101 fn void() {
102 let context = create_context();
103
104 assert_eq!(
105 super::void(&context),
106 Type::parse(&context, "!llvm.void").unwrap()
107 );
108 }
109
110 #[test]
111 fn array() {
112 let context = create_context();
113 let i32 = IntegerType::new(&context, 32).into();
114
115 assert_eq!(
116 super::array(i32, 4),
117 Type::parse(&context, "!llvm.array<4 x i32>").unwrap()
118 );
119 }
120
121 #[test]
122 fn function() {
123 let context = create_context();
124 let i8 = IntegerType::new(&context, 8).into();
125 let i32 = IntegerType::new(&context, 32).into();
126 let i64 = IntegerType::new(&context, 64).into();
127
128 assert_eq!(
129 super::function(i8, &[i32, i64], false),
130 Type::parse(&context, "!llvm.func<i8 (i32, i64)>").unwrap()
131 );
132 }
133
134 #[test]
135 fn r#struct() {
136 let context = create_context();
137 let i32 = IntegerType::new(&context, 32).into();
138 let i64 = IntegerType::new(&context, 64).into();
139
140 assert_eq!(
141 super::r#struct(&context, &[i32, i64], false),
142 Type::parse(&context, "!llvm.struct<(i32, i64)>").unwrap()
143 );
144 }
145
146 #[test]
147 fn packed_struct() {
148 let context = create_context();
149 let i32 = IntegerType::new(&context, 32).into();
150 let i64 = IntegerType::new(&context, 64).into();
151
152 assert_eq!(
153 super::r#struct(&context, &[i32, i64], true),
154 Type::parse(&context, "!llvm.struct<packed (i32, i64)>").unwrap()
155 );
156 }
157}