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