inkwell/values/
traits.rs
1use llvm_sys::prelude::LLVMValueRef;
2
3#[llvm_versions(12..)]
4use llvm_sys::core::LLVMIsPoison;
5
6use std::fmt::Debug;
7
8use crate::support::LLVMString;
9use crate::types::{
10 FloatMathType, FloatType, IntMathType, IntType, PointerMathType, PointerType, ScalableVectorType, VectorType,
11};
12use crate::values::{
13 AggregateValueEnum, AnyValueEnum, ArrayValue, BasicValueEnum, BasicValueUse, CallSiteValue, FloatValue,
14 FunctionValue, GlobalValue, InstructionValue, IntValue, PhiValue, PointerValue, ScalableVectorValue, StructValue,
15 Value, VectorValue,
16};
17
18use super::{BasicMetadataValueEnum, MetadataValue};
19
20pub unsafe trait AsValueRef {
24 fn as_value_ref(&self) -> LLVMValueRef;
25}
26
27macro_rules! trait_value_set {
28 ($trait_name:ident: $($args:ident),*) => (
29 $(
30 unsafe impl<'ctx> $trait_name<'ctx> for $args<'ctx> {}
31 )*
32
33 );
36}
37
38macro_rules! math_trait_value_set {
39 ($trait_name:ident: $(($value_type:ident => $base_type:ident)),*) => (
40 $(
41 unsafe impl<'ctx> $trait_name<'ctx> for $value_type<'ctx> {
42 type BaseType = $base_type<'ctx>;
43 unsafe fn new(value: LLVMValueRef) -> $value_type<'ctx> {
44 unsafe {
45 $value_type::new(value)
46 }
47 }
48 }
49 )*
50 )
51}
52
53macro_rules! base_trait_value_set {
54 ($trait_name:ident: $($value_type:ident),*) => (
55 $(
56 unsafe impl<'ctx> $trait_name<'ctx> for $value_type<'ctx> {
57 unsafe fn new(value: LLVMValueRef) -> $value_type<'ctx> {
58 unsafe {
59 $value_type::new(value)
60 }
61 }
62 }
63 )*
64 )
65}
66
67pub unsafe trait AggregateValue<'ctx>: BasicValue<'ctx> {
69 fn as_aggregate_value_enum(&self) -> AggregateValueEnum<'ctx> {
71 unsafe { AggregateValueEnum::new(self.as_value_ref()) }
72 }
73
74 #[llvm_versions(..=14)]
78 fn const_extract_value(&self, indexes: &mut [u32]) -> BasicValueEnum<'ctx> {
79 use llvm_sys::core::LLVMConstExtractValue;
80
81 unsafe {
82 BasicValueEnum::new(LLVMConstExtractValue(
83 self.as_value_ref(),
84 indexes.as_mut_ptr(),
85 indexes.len() as u32,
86 ))
87 }
88 }
89
90 #[llvm_versions(..=14)]
92 fn const_insert_value<BV: BasicValue<'ctx>>(&self, value: BV, indexes: &mut [u32]) -> BasicValueEnum<'ctx> {
93 use llvm_sys::core::LLVMConstInsertValue;
94
95 unsafe {
96 BasicValueEnum::new(LLVMConstInsertValue(
97 self.as_value_ref(),
98 value.as_value_ref(),
99 indexes.as_mut_ptr(),
100 indexes.len() as u32,
101 ))
102 }
103 }
104}
105
106pub unsafe trait BasicValue<'ctx>: AnyValue<'ctx> {
108 fn as_basic_value_enum(&self) -> BasicValueEnum<'ctx> {
110 unsafe { BasicValueEnum::new(self.as_value_ref()) }
111 }
112
113 fn as_instruction_value(&self) -> Option<InstructionValue<'ctx>> {
116 let value = unsafe { Value::new(self.as_value_ref()) };
117
118 if !value.is_instruction() {
119 return None;
120 }
121
122 unsafe { Some(InstructionValue::new(self.as_value_ref())) }
123 }
124
125 fn get_first_use(&self) -> Option<BasicValueUse> {
126 unsafe { Value::new(self.as_value_ref()).get_first_use() }
127 }
128
129 fn set_name(&self, name: &str) {
131 unsafe { Value::new(self.as_value_ref()).set_name(name) }
132 }
133
134 }
137
138pub unsafe trait IntMathValue<'ctx>: BasicValue<'ctx> {
140 type BaseType: IntMathType<'ctx>;
141 unsafe fn new(value: LLVMValueRef) -> Self;
142}
143
144pub unsafe trait FloatMathValue<'ctx>: BasicValue<'ctx> {
146 type BaseType: FloatMathType<'ctx>;
147 unsafe fn new(value: LLVMValueRef) -> Self;
148}
149
150pub unsafe trait PointerMathValue<'ctx>: BasicValue<'ctx> {
151 type BaseType: PointerMathType<'ctx>;
152 unsafe fn new(value: LLVMValueRef) -> Self;
153}
154
155pub unsafe trait VectorBaseValue<'ctx>: BasicValue<'ctx> {
157 unsafe fn new(value: LLVMValueRef) -> Self;
158}
159
160pub unsafe trait AnyValue<'ctx>: AsValueRef + Debug {
163 fn as_any_value_enum(&self) -> AnyValueEnum<'ctx> {
165 unsafe { AnyValueEnum::new(self.as_value_ref()) }
166 }
167
168 fn print_to_string(&self) -> LLVMString {
170 unsafe { Value::new(self.as_value_ref()).print_to_string() }
171 }
172
173 #[llvm_versions(12..)]
175 fn is_poison(&self) -> bool {
176 unsafe { LLVMIsPoison(self.as_value_ref()) == 1 }
177 }
178}
179
180trait_value_set! {AggregateValue: ArrayValue, AggregateValueEnum, StructValue}
181trait_value_set! {AnyValue: AnyValueEnum, BasicValueEnum, BasicMetadataValueEnum, AggregateValueEnum, ArrayValue, IntValue, FloatValue, GlobalValue, PhiValue, PointerValue, FunctionValue, StructValue, VectorValue, ScalableVectorValue, InstructionValue, CallSiteValue, MetadataValue}
182trait_value_set! {BasicValue: ArrayValue, BasicValueEnum, AggregateValueEnum, IntValue, FloatValue, GlobalValue, StructValue, PointerValue, VectorValue, ScalableVectorValue}
183math_trait_value_set! {IntMathValue: (IntValue => IntType), (VectorValue => VectorType), (ScalableVectorValue => ScalableVectorType), (PointerValue => IntType)}
184math_trait_value_set! {FloatMathValue: (FloatValue => FloatType), (VectorValue => VectorType), (ScalableVectorValue => ScalableVectorType)}
185math_trait_value_set! {PointerMathValue: (PointerValue => PointerType), (VectorValue => VectorType), (ScalableVectorValue => ScalableVectorType)}
186base_trait_value_set! {VectorBaseValue: VectorValue, ScalableVectorValue}