llvm_plugin_inkwell/values/
traits.rs1use llvm_sys::prelude::LLVMValueRef;
2
3use std::fmt::Debug;
4
5use crate::support::LLVMString;
6use crate::types::{FloatMathType, FloatType, IntMathType, IntType, PointerMathType, PointerType, VectorType};
7use crate::values::{
8 AggregateValueEnum, AnyValueEnum, ArrayValue, BasicValueEnum, BasicValueUse, CallSiteValue, FloatValue,
9 FunctionValue, GlobalValue, InstructionValue, IntValue, PhiValue, PointerValue, StructValue, Value, VectorValue,
10};
11
12use super::{BasicMetadataValueEnum, MetadataValue};
13
14pub unsafe trait AsValueRef {
18 fn as_value_ref(&self) -> LLVMValueRef;
19}
20
21macro_rules! trait_value_set {
22 ($trait_name:ident: $($args:ident),*) => (
23 $(
24 unsafe impl<'ctx> $trait_name<'ctx> for $args<'ctx> {}
25 )*
26
27 );
30}
31
32macro_rules! math_trait_value_set {
33 ($trait_name:ident: $(($value_type:ident => $base_type:ident)),*) => (
34 $(
35 unsafe impl<'ctx> $trait_name<'ctx> for $value_type<'ctx> {
36 type BaseType = $base_type<'ctx>;
37 unsafe fn new(value: LLVMValueRef) -> $value_type<'ctx> {
38 unsafe {
39 $value_type::new(value)
40 }
41 }
42 }
43 )*
44 )
45}
46
47pub unsafe trait AggregateValue<'ctx>: BasicValue<'ctx> {
49 fn as_aggregate_value_enum(&self) -> AggregateValueEnum<'ctx> {
51 unsafe { AggregateValueEnum::new(self.as_value_ref()) }
52 }
53
54 #[llvm_versions(4.0..=14.0)]
58 fn const_extract_value(&self, indexes: &mut [u32]) -> BasicValueEnum<'ctx> {
59 use llvm_sys::core::LLVMConstExtractValue;
60
61 unsafe {
62 BasicValueEnum::new(LLVMConstExtractValue(
63 self.as_value_ref(),
64 indexes.as_mut_ptr(),
65 indexes.len() as u32,
66 ))
67 }
68 }
69
70 #[llvm_versions(4.0..=14.0)]
72 fn const_insert_value<BV: BasicValue<'ctx>>(&self, value: BV, indexes: &mut [u32]) -> BasicValueEnum<'ctx> {
73 use llvm_sys::core::LLVMConstInsertValue;
74
75 unsafe {
76 BasicValueEnum::new(LLVMConstInsertValue(
77 self.as_value_ref(),
78 value.as_value_ref(),
79 indexes.as_mut_ptr(),
80 indexes.len() as u32,
81 ))
82 }
83 }
84}
85
86pub unsafe trait BasicValue<'ctx>: AnyValue<'ctx> {
88 fn as_basic_value_enum(&self) -> BasicValueEnum<'ctx> {
90 unsafe { BasicValueEnum::new(self.as_value_ref()) }
91 }
92
93 fn as_instruction_value(&self) -> Option<InstructionValue<'ctx>> {
96 let value = unsafe { Value::new(self.as_value_ref()) };
97
98 if !value.is_instruction() {
99 return None;
100 }
101
102 unsafe { Some(InstructionValue::new(self.as_value_ref())) }
103 }
104
105 fn get_first_use(&self) -> Option<BasicValueUse> {
106 unsafe { Value::new(self.as_value_ref()).get_first_use() }
107 }
108
109 fn set_name(&self, name: &str) {
111 unsafe { Value::new(self.as_value_ref()).set_name(name) }
112 }
113
114 }
117
118pub unsafe trait IntMathValue<'ctx>: BasicValue<'ctx> {
120 type BaseType: IntMathType<'ctx>;
121 unsafe fn new(value: LLVMValueRef) -> Self;
122}
123
124pub unsafe trait FloatMathValue<'ctx>: BasicValue<'ctx> {
126 type BaseType: FloatMathType<'ctx>;
127 unsafe fn new(value: LLVMValueRef) -> Self;
128}
129
130pub unsafe trait PointerMathValue<'ctx>: BasicValue<'ctx> {
131 type BaseType: PointerMathType<'ctx>;
132 unsafe fn new(value: LLVMValueRef) -> Self;
133}
134
135pub unsafe trait AnyValue<'ctx>: AsValueRef + Debug {
138 fn as_any_value_enum(&self) -> AnyValueEnum<'ctx> {
140 unsafe { AnyValueEnum::new(self.as_value_ref()) }
141 }
142
143 fn print_to_string(&self) -> LLVMString {
145 unsafe { Value::new(self.as_value_ref()).print_to_string() }
146 }
147}
148
149trait_value_set! {AggregateValue: ArrayValue, AggregateValueEnum, StructValue}
150trait_value_set! {AnyValue: AnyValueEnum, BasicValueEnum, BasicMetadataValueEnum, AggregateValueEnum, ArrayValue, IntValue, FloatValue, GlobalValue, PhiValue, PointerValue, FunctionValue, StructValue, VectorValue, InstructionValue, CallSiteValue, MetadataValue}
151trait_value_set! {BasicValue: ArrayValue, BasicValueEnum, AggregateValueEnum, IntValue, FloatValue, GlobalValue, StructValue, PointerValue, VectorValue}
152math_trait_value_set! {IntMathValue: (IntValue => IntType), (VectorValue => VectorType), (PointerValue => IntType)}
153math_trait_value_set! {FloatMathValue: (FloatValue => FloatType), (VectorValue => VectorType)}
154math_trait_value_set! {PointerMathValue: (PointerValue => PointerType), (VectorValue => VectorType)}