inkwell/types/
traits.rs

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
17/// Accessor to the inner LLVM type reference
18pub unsafe trait AsTypeRef {
19    /// Returns the internal LLVM reference behind the type
20    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
31/// Represents any LLVM type.
32pub unsafe trait AnyType<'ctx>: AsTypeRef + Debug {
33    /// Returns an `AnyTypeEnum` that represents the current type.
34    fn as_any_type_enum(&self) -> AnyTypeEnum<'ctx> {
35        unsafe { AnyTypeEnum::new(self.as_type_ref()) }
36    }
37
38    /// Prints the definition of a Type to a `LLVMString`.
39    fn print_to_string(&self) -> LLVMString {
40        unsafe { Type::new(self.as_type_ref()).print_to_string() }
41    }
42}
43
44/// Represents a basic LLVM type, that may be used in functions and struct definitions.
45pub unsafe trait BasicType<'ctx>: AnyType<'ctx> {
46    /// Returns a `BasicTypeEnum` that represents the current type.
47    fn as_basic_type_enum(&self) -> BasicTypeEnum<'ctx> {
48        unsafe { BasicTypeEnum::new(self.as_type_ref()) }
49    }
50
51    /// Create a `FunctionType` with this `BasicType` as its return type.
52    ///
53    /// # Example:
54    ///
55    /// ```no_run
56    /// use inkwell::context::Context;
57    /// use inkwell::types::BasicType;
58    ///
59    /// let context = Context::create();
60    /// let int = context.i32_type();
61    /// let int_basic_type = int.as_basic_type_enum();
62    /// assert_eq!(int_basic_type.fn_type(&[], false), int.fn_type(&[], false));
63    /// ```
64    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    /// Determines whether or not this `BasicType` is sized or not.
69    /// For example, opaque structs are unsized.
70    ///
71    /// # Example
72    ///
73    /// ```no_run
74    /// use inkwell::context::Context;
75    /// use inkwell::types::BasicType;
76    ///
77    /// let context = Context::create();
78    /// let f32_type = context.f32_type();
79    /// let f32_vec_type = f32_type.vec_type(40);
80    ///
81    /// assert!(f32_vec_type.is_sized());
82    /// ```
83    fn is_sized(&self) -> bool {
84        unsafe { Type::new(self.as_type_ref()).is_sized() }
85    }
86
87    /// Gets the size of this `BasicType`. Value may vary depending on the target architecture.
88    ///
89    /// # Example
90    ///
91    /// ```no_run
92    /// use inkwell::context::Context;
93    /// use inkwell::types::BasicType;
94    ///
95    /// let context = Context::create();
96    /// let f32_type = context.f32_type();
97    /// let f32_basic_type = f32_type.as_basic_type_enum();
98    /// let f32_type_size = f32_basic_type.size_of();
99    /// ```
100    fn size_of(&self) -> Option<IntValue<'ctx>> {
101        unsafe { Type::new(self.as_type_ref()).size_of() }
102    }
103
104    /// Create an `ArrayType` with this `BasicType` as its elements.
105    ///
106    /// Example:
107    /// ```no_run
108    /// use inkwell::context::Context;
109    /// use inkwell::types::BasicType;
110    ///
111    /// let context = Context::create();
112    /// let int = context.i32_type();
113    /// let int_basic_type = int.as_basic_type_enum();
114    /// assert_eq!(int_basic_type.array_type(32), int.array_type(32));
115    /// ```
116    // FIXME: This likely doesn't belong on the trait, since not all basic types can be turned into arrays?
117    fn array_type(&self, size: u32) -> ArrayType<'ctx> {
118        unsafe { Type::new(self.as_type_ref()).array_type(size) }
119    }
120
121    /// Create a `PointerType` that points to this `BasicType`.
122    ///
123    /// Example:
124    /// ```no_run
125    /// use inkwell::context::Context;
126    /// use inkwell::types::BasicType;
127    /// use inkwell::AddressSpace;
128    ///
129    /// let context = Context::create();
130    /// let int = context.i32_type();
131    /// let int_basic_type = int.as_basic_type_enum();
132    /// let addr_space = AddressSpace::default();
133    /// assert_eq!(int_basic_type.ptr_type(addr_space), int.ptr_type(addr_space));
134    /// ```
135    #[cfg_attr(
136        any(
137            all(feature = "llvm15-0", not(feature = "typed-pointers")),
138            all(feature = "llvm16-0", not(feature = "typed-pointers")),
139            feature = "llvm17-0",
140            feature = "llvm18-0"
141        ),
142        deprecated(
143            note = "Starting from version 15.0, LLVM doesn't differentiate between pointer types. Use Context::ptr_type instead."
144        )
145    )]
146    fn ptr_type(&self, address_space: AddressSpace) -> PointerType<'ctx> {
147        unsafe { Type::new(self.as_type_ref()).ptr_type(address_space) }
148    }
149}
150
151/// Represents an LLVM type that can have integer math operations applied to it.
152pub unsafe trait IntMathType<'ctx>: BasicType<'ctx> {
153    /// The value instance of an int or int vector type.
154    type ValueType: IntMathValue<'ctx>;
155    /// The type for int to float or int vector to float vector conversions.
156    type MathConvType: FloatMathType<'ctx>;
157    /// The type for int to pointer or int vector to pointer vector conversions.
158    type PtrConvType: PointerMathType<'ctx>;
159}
160
161/// Represents an LLVM type that can have floating point math operations applied to it.
162pub unsafe trait FloatMathType<'ctx>: BasicType<'ctx> {
163    /// The value instance of a float or float vector type.
164    type ValueType: FloatMathValue<'ctx>;
165    /// The type for float to int or float vector to int vector conversions.
166    type MathConvType: IntMathType<'ctx>;
167}
168
169/// Represents an LLVM type that can have pointer operations applied to it.
170pub unsafe trait PointerMathType<'ctx>: BasicType<'ctx> {
171    /// The value instance of a pointer type.
172    type ValueType: PointerMathValue<'ctx>;
173    /// The type for pointer to int or pointer vector to int conversions.
174    type PtrConvType: IntMathType<'ctx>;
175}
176
177trait_type_set! {AnyType: AnyTypeEnum, BasicTypeEnum, IntType, FunctionType, FloatType, PointerType, StructType, ArrayType, VoidType, VectorType, ScalableVectorType}
178trait_type_set! {BasicType: BasicTypeEnum, IntType, FloatType, PointerType, StructType, ArrayType, VectorType, ScalableVectorType}
179
180unsafe impl<'ctx> IntMathType<'ctx> for IntType<'ctx> {
181    type ValueType = IntValue<'ctx>;
182    type MathConvType = FloatType<'ctx>;
183    type PtrConvType = PointerType<'ctx>;
184}
185
186unsafe impl<'ctx> IntMathType<'ctx> for VectorType<'ctx> {
187    type ValueType = VectorValue<'ctx>;
188    type MathConvType = VectorType<'ctx>;
189    type PtrConvType = VectorType<'ctx>;
190}
191
192unsafe impl<'ctx> IntMathType<'ctx> for ScalableVectorType<'ctx> {
193    type ValueType = ScalableVectorValue<'ctx>;
194    type MathConvType = ScalableVectorType<'ctx>;
195    type PtrConvType = ScalableVectorType<'ctx>;
196}
197
198unsafe impl<'ctx> FloatMathType<'ctx> for FloatType<'ctx> {
199    type ValueType = FloatValue<'ctx>;
200    type MathConvType = IntType<'ctx>;
201}
202
203unsafe impl<'ctx> FloatMathType<'ctx> for VectorType<'ctx> {
204    type ValueType = VectorValue<'ctx>;
205    type MathConvType = VectorType<'ctx>;
206}
207
208unsafe impl<'ctx> FloatMathType<'ctx> for ScalableVectorType<'ctx> {
209    type ValueType = ScalableVectorValue<'ctx>;
210    type MathConvType = ScalableVectorType<'ctx>;
211}
212
213unsafe impl<'ctx> PointerMathType<'ctx> for PointerType<'ctx> {
214    type ValueType = PointerValue<'ctx>;
215    type PtrConvType = IntType<'ctx>;
216}
217
218unsafe impl<'ctx> PointerMathType<'ctx> for VectorType<'ctx> {
219    type ValueType = VectorValue<'ctx>;
220    type PtrConvType = VectorType<'ctx>;
221}
222
223unsafe impl<'ctx> PointerMathType<'ctx> for ScalableVectorType<'ctx> {
224    type ValueType = ScalableVectorValue<'ctx>;
225    type PtrConvType = ScalableVectorType<'ctx>;
226}