llvm_plugin_inkwell/values/
array_value.rs1use llvm_sys::core::{LLVMIsAConstantArray, LLVMIsAConstantDataArray, LLVMIsConstantString, LLVMGetAsString};
2use llvm_sys::prelude::LLVMValueRef;
3
4use std::ffi::CStr;
5use std::fmt::{self, Display};
6
7use crate::types::ArrayType;
8use crate::values::traits::{AnyValue, AsValueRef};
9use crate::values::{InstructionValue, Value};
10
11#[derive(PartialEq, Eq, Clone, Copy, Hash)]
13pub struct ArrayValue<'ctx> {
14 array_value: Value<'ctx>,
15}
16
17impl<'ctx> ArrayValue<'ctx> {
18 pub(crate) unsafe fn new(value: LLVMValueRef) -> Self {
19 assert!(!value.is_null());
20
21 ArrayValue {
22 array_value: Value::new(value),
23 }
24 }
25
26 pub fn get_name(&self) -> &CStr {
29 self.array_value.get_name()
30 }
31
32 pub fn set_name(&self, name: &str) {
34 self.array_value.set_name(name)
35 }
36
37 pub fn get_type(self) -> ArrayType<'ctx> {
39 unsafe { ArrayType::new(self.array_value.get_type()) }
40 }
41
42 pub fn is_null(self) -> bool {
44 self.array_value.is_null()
45 }
46
47 pub fn is_undef(self) -> bool {
49 self.array_value.is_undef()
50 }
51
52 pub fn print_to_stderr(self) {
54 self.array_value.print_to_stderr()
55 }
56
57 pub fn as_instruction(self) -> Option<InstructionValue<'ctx>> {
59 self.array_value.as_instruction()
60 }
61
62 pub fn replace_all_uses_with(self, other: ArrayValue<'ctx>) {
65 self.array_value.replace_all_uses_with(other.as_value_ref())
66 }
67
68 pub fn is_const(self) -> bool {
83 self.array_value.is_const()
84 }
85
86 pub fn is_const_string(self) -> bool {
100 unsafe { LLVMIsConstantString(self.as_value_ref()) == 1 }
101 }
102
103 pub fn get_string_constant(&self) -> Option<&CStr> {
120 let mut len = 0;
121 let ptr = unsafe { LLVMGetAsString(self.as_value_ref(), &mut len) };
122
123 if ptr.is_null() {
124 None
125 } else {
126 unsafe { Some(CStr::from_ptr(ptr)) }
127 }
128 }
129
130 pub fn is_const_data_array(self) -> bool {
132 unsafe { !LLVMIsAConstantDataArray(self.as_value_ref()).is_null() }
133 }
134}
135
136unsafe impl AsValueRef for ArrayValue<'_> {
137 fn as_value_ref(&self) -> LLVMValueRef {
138 self.array_value.value
139 }
140}
141
142impl Display for ArrayValue<'_> {
143 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
144 write!(f, "{}", self.print_to_string())
145 }
146}
147
148impl fmt::Debug for ArrayValue<'_> {
149 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
150 let llvm_value = self.print_to_string();
151 let llvm_type = self.get_type();
152 let name = self.get_name();
153 let is_const = self.is_const();
154 let is_null = self.is_null();
155 let is_const_array = unsafe { !LLVMIsAConstantArray(self.as_value_ref()).is_null() };
156 let is_const_data_array = self.is_const_data_array();
157
158 f.debug_struct("ArrayValue")
159 .field("name", &name)
160 .field("address", &self.as_value_ref())
161 .field("is_const", &is_const)
162 .field("is_const_array", &is_const_array)
163 .field("is_const_data_array", &is_const_data_array)
164 .field("is_null", &is_null)
165 .field("llvm_value", &llvm_value)
166 .field("llvm_type", &llvm_type)
167 .finish()
168 }
169}