1use llvm_sys::prelude::LLVMTypeRef;
2
3use std::fmt::Debug;
4
5use crate::support::LLVMString;
6use crate::types::enums::{AnyTypeEnum, BasicMetadataTypeEnum, BasicTypeEnum};
7use crate::types::{
8 ArrayType, FloatType, FunctionType, IntType, PointerType, ScalableVectorType, StructType, Type, VectorType,
9 VoidType,
10};
11use crate::values::{
12 FloatMathValue, FloatValue, IntMathValue, IntValue, PointerMathValue, PointerValue, ScalableVectorValue,
13 VectorValue,
14};
15use crate::AddressSpace;
16
17pub unsafe trait AsTypeRef {
19 fn as_type_ref(&self) -> LLVMTypeRef;
21}
22
23macro_rules! trait_type_set {
24 ($trait_name:ident: $($args:ident),*) => (
25 $(
26 unsafe impl<'ctx> $trait_name<'ctx> for $args<'ctx> {}
27 )*
28 );
29}
30
31pub unsafe trait AnyType<'ctx>: AsTypeRef + Debug {
33 fn as_any_type_enum(&self) -> AnyTypeEnum<'ctx> {
35 unsafe { AnyTypeEnum::new(self.as_type_ref()) }
36 }
37
38 fn print_to_string(&self) -> LLVMString {
40 unsafe { Type::new(self.as_type_ref()).print_to_string() }
41 }
42}
43
44pub unsafe trait BasicType<'ctx>: AnyType<'ctx> {
46 fn as_basic_type_enum(&self) -> BasicTypeEnum<'ctx> {
48 unsafe { BasicTypeEnum::new(self.as_type_ref()) }
49 }
50
51 fn fn_type(&self, param_types: &[BasicMetadataTypeEnum<'ctx>], is_var_args: bool) -> FunctionType<'ctx> {
65 unsafe { Type::new(self.as_type_ref()).fn_type(param_types, is_var_args) }
66 }
67
68 fn is_sized(&self) -> bool {
84 unsafe { Type::new(self.as_type_ref()).is_sized() }
85 }
86
87 fn size_of(&self) -> Option<IntValue<'ctx>> {
101 unsafe { Type::new(self.as_type_ref()).size_of() }
102 }
103
104 fn get_alignment(&self) -> IntValue<'ctx> {
119 unsafe { Type::new(self.as_type_ref()).get_alignment() }
120 }
121
122 fn array_type(&self, size: u32) -> ArrayType<'ctx> {
136 unsafe { Type::new(self.as_type_ref()).array_type(size) }
137 }
138
139 #[cfg_attr(
154 any(
155 all(feature = "llvm15-0", not(feature = "typed-pointers")),
156 all(feature = "llvm16-0", not(feature = "typed-pointers")),
157 feature = "llvm17-0",
158 feature = "llvm18-1",
159 feature = "llvm19-1",
160 feature = "llvm20-1",
161 feature = "llvm21-1",
162 ),
163 deprecated(
164 note = "Starting from version 15.0, LLVM doesn't differentiate between pointer types. Use Context::ptr_type instead."
165 )
166 )]
167 fn ptr_type(&self, address_space: AddressSpace) -> PointerType<'ctx> {
168 unsafe { Type::new(self.as_type_ref()).ptr_type(address_space) }
169 }
170}
171
172pub unsafe trait IntMathType<'ctx>: BasicType<'ctx> {
174 type ValueType: IntMathValue<'ctx>;
176 type MathConvType: FloatMathType<'ctx>;
178 type PtrConvType: PointerMathType<'ctx>;
180}
181
182pub unsafe trait FloatMathType<'ctx>: BasicType<'ctx> {
184 type ValueType: FloatMathValue<'ctx>;
186 type MathConvType: IntMathType<'ctx>;
188}
189
190pub unsafe trait PointerMathType<'ctx>: BasicType<'ctx> {
192 type ValueType: PointerMathValue<'ctx>;
194 type PtrConvType: IntMathType<'ctx>;
196}
197
198trait_type_set! {AnyType: AnyTypeEnum, BasicTypeEnum, IntType, FunctionType, FloatType, PointerType, StructType, ArrayType, VoidType, VectorType, ScalableVectorType}
199trait_type_set! {BasicType: BasicTypeEnum, IntType, FloatType, PointerType, StructType, ArrayType, VectorType, ScalableVectorType}
200
201unsafe impl<'ctx> IntMathType<'ctx> for IntType<'ctx> {
202 type ValueType = IntValue<'ctx>;
203 type MathConvType = FloatType<'ctx>;
204 type PtrConvType = PointerType<'ctx>;
205}
206
207unsafe impl<'ctx> IntMathType<'ctx> for VectorType<'ctx> {
208 type ValueType = VectorValue<'ctx>;
209 type MathConvType = VectorType<'ctx>;
210 type PtrConvType = VectorType<'ctx>;
211}
212
213unsafe impl<'ctx> IntMathType<'ctx> for ScalableVectorType<'ctx> {
214 type ValueType = ScalableVectorValue<'ctx>;
215 type MathConvType = ScalableVectorType<'ctx>;
216 type PtrConvType = ScalableVectorType<'ctx>;
217}
218
219unsafe impl<'ctx> FloatMathType<'ctx> for FloatType<'ctx> {
220 type ValueType = FloatValue<'ctx>;
221 type MathConvType = IntType<'ctx>;
222}
223
224unsafe impl<'ctx> FloatMathType<'ctx> for VectorType<'ctx> {
225 type ValueType = VectorValue<'ctx>;
226 type MathConvType = VectorType<'ctx>;
227}
228
229unsafe impl<'ctx> FloatMathType<'ctx> for ScalableVectorType<'ctx> {
230 type ValueType = ScalableVectorValue<'ctx>;
231 type MathConvType = ScalableVectorType<'ctx>;
232}
233
234unsafe impl<'ctx> PointerMathType<'ctx> for PointerType<'ctx> {
235 type ValueType = PointerValue<'ctx>;
236 type PtrConvType = IntType<'ctx>;
237}
238
239unsafe impl<'ctx> PointerMathType<'ctx> for VectorType<'ctx> {
240 type ValueType = VectorValue<'ctx>;
241 type PtrConvType = VectorType<'ctx>;
242}
243
244unsafe impl<'ctx> PointerMathType<'ctx> for ScalableVectorType<'ctx> {
245 type ValueType = ScalableVectorValue<'ctx>;
246 type PtrConvType = ScalableVectorType<'ctx>;
247}